Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

jcheck: add "problemlists" check #518

Closed
wants to merge 10 commits into from
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -228,4 +228,11 @@ public void visit(BlacklistIssue issue) {
public void visit(BinaryIssue issue) {
log.fine("ignored: binary file");
}

@Override
public void visit(ProblemListsIssue issue) {
failedChecks.add(issue.check().getClass());
messages.add(issue.issue() + " is used in problem lists: " + issue.files());
readyForReview = false;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -304,6 +304,14 @@ public void visit(BinaryIssue i) {
}
}

@Override
public void visit(ProblemListsIssue i) {
if (!ignore.contains(i.check().name())) {
println(i, i.issue() + " is used in problem lists " + i.files());
hasDisplayedErrors = true;
}
}

public boolean hasDisplayedErrors() {
return hasDisplayedErrors;
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,6 @@
import org.openjdk.skara.ini.Section;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

public class ChecksConfiguration {
@@ -36,7 +35,8 @@ public class ChecksConfiguration {
ReviewersConfiguration.DEFAULT,
MergeConfiguration.DEFAULT,
CommitterConfiguration.DEFAULT,
IssuesConfiguration.DEFAULT);
IssuesConfiguration.DEFAULT,
ProblemListsConfiguration.DEFAULT);

private final List<String> error;
private final List<String> warning;
@@ -45,21 +45,24 @@ public class ChecksConfiguration {
private final MergeConfiguration merge;
private final CommitterConfiguration committer;
private final IssuesConfiguration issues;
private final ProblemListsConfiguration problemlists;

ChecksConfiguration(List<String> error,
List<String> warning,
WhitespaceConfiguration whitespace,
ReviewersConfiguration reviewers,
MergeConfiguration merge,
CommitterConfiguration committer,
IssuesConfiguration issues) {
IssuesConfiguration issues,
ProblemListsConfiguration problemlists) {
this.error = error;
this.warning = warning;
this.whitespace = whitespace;
this.reviewers = reviewers;
this.merge = merge;
this.committer = committer;
this.issues = issues;
this.problemlists = problemlists;
}

public List<String> error() {
@@ -108,6 +111,10 @@ public IssuesConfiguration issues() {
return issues;
}

public ProblemListsConfiguration problemlists() {
return problemlists;
}

static String name() {
return "checks";
}
@@ -125,7 +132,7 @@ static ChecksConfiguration parse(Section s) {
var merge = MergeConfiguration.parse(s.subsection(MergeConfiguration.name()));
var committer = CommitterConfiguration.parse(s.subsection(CommitterConfiguration.name()));
var issues = IssuesConfiguration.parse(s.subsection(IssuesConfiguration.name()));

return new ChecksConfiguration(error, warning, whitespace, reviewers, merge, committer, issues);
var problemlists = ProblemListsConfiguration.parse(s.subsection(ProblemListsConfiguration.name()));
return new ChecksConfiguration(error, warning, whitespace, reviewers, merge, committer, issues, problemlists);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -44,4 +44,5 @@ public interface IssueVisitor {
void visit(BlacklistIssue issue);
void visit(BinaryIssue issue);
void visit(SymlinkIssue issue);
void visit(ProblemListsIssue problemListIssue);
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -78,6 +78,7 @@ public class JCheck {
new IssuesCheck(utils),
new ExecutableCheck(),
new SymlinkCheck(),
new ProblemListsCheck(repository),
new BlacklistCheck(blacklist)
);
repositoryChecks = List.of(
@@ -0,0 +1,110 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.openjdk.skara.jcheck;

import org.openjdk.skara.vcs.Commit;
import org.openjdk.skara.vcs.FileEntry;
import org.openjdk.skara.vcs.Hash;
import org.openjdk.skara.vcs.ReadOnlyRepository;
import org.openjdk.skara.vcs.openjdk.CommitMessage;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Path;
import java.util.*;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import java.util.stream.Stream;

public class ProblemListsCheck extends CommitCheck {
private final Logger log = Logger.getLogger("org.openjdk.skara.jcheck.problemlists");
private static final Pattern WHITESPACES = Pattern.compile("\\s+");

private final ReadOnlyRepository repo;

ProblemListsCheck(ReadOnlyRepository repo) {
this.repo = repo;
}

private Stream<String> getProblemListedIssues(Path path, Hash hash){
try {
var lines = repo.lines(path, hash);
if (lines.isEmpty()) {
return Stream.empty();
}
return lines.get()
.stream()
.map(String::trim)
.filter(s -> !s.startsWith("#"))
.map(WHITESPACES::split)
.filter(ss -> ss.length > 1)
.map(ss -> ss[1])
.flatMap(s -> Arrays.stream(s.split(",")));
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}

@Override
Iterator<Issue> check(Commit commit, CommitMessage message, JCheckConfiguration conf) {
var problemListed = new HashMap<String, List<Path>>();
var checkConf = conf.checks().problemlists();
var dirs = checkConf.dirs();
var pattern = Pattern.compile(checkConf.pattern()).asMatchPredicate();
try {
var hash = commit.hash();
for (var dir : dirs.split("\\|")) {
repo.files(hash, Path.of(dir))
.stream()
.map(FileEntry::path)
.filter(p -> pattern.test(p.getFileName().toString()))
.forEach(p -> getProblemListedIssues(p, commit.hash()).forEach(t -> problemListed.compute(t,
(k, v) -> {if (v == null) v = new ArrayList<>(); v.add(p); return v;})));
}
} catch (IOException e) {
throw new UncheckedIOException(e);
}

var metadata = CommitIssue.metadata(commit, message, conf, this);
var issues = new ArrayList<Issue>();
for (var issue : message.issues()) {
var problemLists = problemListed.get(issue.id());
if (problemLists != null) {
log.finer(String.format("issue: %s is found in problem lists: %s", issue.id(), problemLists));
issues.add(new ProblemListsIssue(metadata, issue.id(), new HashSet<>(problemLists)));
}
}

return issues.iterator();
}

@Override
public String name() {
return "problemlists";
}

@Override
public String description() {
return "Fixed issue should not be in a problem list";
}
}
@@ -0,0 +1,60 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.openjdk.skara.jcheck;

import org.openjdk.skara.ini.Section;

public class ProblemListsConfiguration {
static final ProblemListsConfiguration DEFAULT =
new ProblemListsConfiguration("test", "^ProblemList.*.txt$");

private final String dirs;
private final String pattern;

ProblemListsConfiguration(String dirs, String patterns) {
this.dirs = dirs;
this.pattern = patterns;
}

public String dirs() {
return dirs;
}

public String pattern() {
return pattern;
}

static String name() {
return "problemlists";
}

static ProblemListsConfiguration parse(Section s) {
if (s == null) {
return DEFAULT;
}

var dirs = s.get("dirs", DEFAULT.dirs());
var pattern = s.get("pattern", DEFAULT.pattern());
return new ProblemListsConfiguration(dirs, pattern);
}
}
@@ -0,0 +1,51 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.openjdk.skara.jcheck;

import java.nio.file.Path;
import java.util.Set;

public class ProblemListsIssue extends CommitIssue {
private final String issue;
private final Set<Path> files;

ProblemListsIssue(CommitIssue.Metadata metadata, String issue, Set<Path> files) {
super(metadata);
this.issue = issue;
this.files = files;
}

@Override
public void accept(IssueVisitor v) {
v.visit(this);
}

public String issue() {
return issue;
}

public Set<Path> files() {
return files;
}
}

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -237,6 +237,11 @@ public void visit(BinaryIssue e) {
issues.add(e);
}

@Override
public void visit(ProblemListsIssue e) {
issues.add(e);
}

Set<Issue> issues() {
return issues;
}