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 symlink check #525

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -206,6 +206,13 @@ public void visit(ExecutableIssue issue) {
readyForReview = false;
}

@Override
public void visit(SymlinkIssue issue) {
messages.add(String.format("Symbolic links are not allowed (file: %s)", issue.path()));
failedChecks.add(issue.check().getClass());
readyForReview = false;
}

@Override
public void visit(BlacklistIssue issue) {
log.fine("ignored: blacklisted commit");
@@ -234,6 +234,13 @@ public void visit(ExecutableIssue i) {
}
}

public void visit(SymlinkIssue i) {
if (!ignore.contains(i.check().name())) {
println(i, "file " + i.path() + " is symbolic link");
hasDisplayedErrors = true;
}
}

public void visit(AuthorNameIssue i) {
if (!ignore.contains(i.check().name())) {
println(i, "missing author name");
@@ -42,4 +42,5 @@ public interface IssueVisitor {
void visit(ExecutableIssue issue);
void visit(BlacklistIssue issue);
void visit(BinaryIssue issue);
void visit(SymlinkIssue issue);
}
@@ -77,6 +77,7 @@ public class JCheck {
new MessageCheck(utils),
new IssuesCheck(utils),
new ExecutableCheck(),
new SymlinkCheck(),
new BlacklistCheck(blacklist)
);
repositoryChecks = List.of(
@@ -73,7 +73,7 @@ private static INI convert(INI old) {
config.add("jbs=JDK");

config.add("[checks]");
var error = "error=blacklist,author,committer,reviewers,merge,hg-tag,message,issues,executable";
var error = "error=blacklist,author,committer,reviewers,merge,hg-tag,message,issues,executable,symlink";
var shouldCheckWhitespace = false;
var checkWhitespace = old.get("whitespace");
if (checkWhitespace == null || !checkWhitespace.asString().equals("lax")) {
@@ -0,0 +1,66 @@
/*
* 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.openjdk.CommitMessage;

import java.util.Iterator;
import java.util.ArrayList;
import java.util.logging.Logger;

public class SymlinkCheck extends CommitCheck {
private final Logger log = Logger.getLogger("org.openjdk.skara.jcheck.symlink");

@Override
Iterator<Issue> check(Commit commit, CommitMessage message, JCheckConfiguration conf) {
var metadata = CommitIssue.metadata(commit, message, conf, this);

var issues = new ArrayList<Issue>();
for (var diff : commit.parentDiffs()) {
for (var patch : diff.patches()) {
if (patch.target().type().isPresent()) {
var type = patch.target().type().get();
if (type.isSymbolicLink()) {
var path = patch.target().path().get();
log.finer("issue: " + path + " is symbolic link");
issues.add(new SymlinkIssue(path, metadata));
}
}
}
}

return issues.iterator();
}

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

@Override
public String description() {
return "Files should not be symbolic links";
}
}

@@ -0,0 +1,44 @@
/*
* 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;

public class SymlinkIssue extends CommitIssue {
private final Path path;

SymlinkIssue(Path path, CommitIssue.Metadata metadata) {
super(metadata);
this.path = path;
}

public Path path() {
return path;
}

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

@@ -197,6 +197,11 @@ public void visit(ExecutableIssue e) {
issues.add(e);
}

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

@Override
public void visit(AuthorNameIssue e) {
issues.add(e);
@@ -0,0 +1,120 @@
/*
* 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.*;
import org.openjdk.skara.vcs.openjdk.*;

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
import java.time.ZonedDateTime;
import java.io.IOException;
import java.nio.file.Path;

class SymlinkCheckTests {
private final Utilities utils = new Utilities();

private static final List<String> CONFIGURATION = List.of(
"[general]",
"project = test",
"[checks]",
"error = symlink"
);

private static JCheckConfiguration conf() {
return JCheckConfiguration.parse(CONFIGURATION);
}

private static List<Diff> symlinkDiff(String filename) {
var patch = new TextualPatch(null, null, Hash.zero(),
Path.of(filename), FileType.fromOctal("120000"), Hash.zero(),
Status.from('A'), List.of());
var diff = new Diff(Hash.zero(), Hash.zero(), List.of(patch));
return List.of(diff);
}

private static List<Diff> diff(String filename, String line) {
var hunk = new Hunk(new Range(1, 0), List.of(),
new Range(1, 1), List.of(line));
var patch = new TextualPatch(Path.of(filename), FileType.fromOctal("100644"), Hash.zero(),
Path.of(filename), FileType.fromOctal("100644"), Hash.zero(),
Status.from('M'), List.of(hunk));
var diff = new Diff(Hash.zero(), Hash.zero(), List.of(patch));
return List.of(diff);
}

private static Commit commit(List<Diff> diffs) {
var author = new Author("foo", "foo@localhost");
var hash = new Hash("0123456789012345678901234567890123456789");
var parents = List.of(hash);
var date = ZonedDateTime.now();
var metadata = new CommitMetadata(hash, parents, author, author, date, List.of("Added symlink"));
return new Commit(metadata, diffs);
}

private static Commit commitWithSymlink(String filename) {
return commit(symlinkDiff(filename));
}

private static Commit commitWithRegularFile(String filename, String line) {
return commit(diff(filename, line));
}

private static CommitMessage message(Commit c) {
return CommitMessageParsers.v1.parse(c);
}

private List<Issue> toList(Iterator<Issue> i) {
var list = new ArrayList<Issue>();
while (i.hasNext()) {
list.add(i.next());
}
return list;
}

@Test
void commitWithSymlinkShouldFail() {
var commit = commitWithSymlink("symlink");
var message = message(commit);
var check = new SymlinkCheck();
var issues = toList(check.check(commit, message, conf()));

assertEquals(1, issues.size());
assertTrue(issues.get(0) instanceof SymlinkIssue);
var issue = (SymlinkIssue) issues.get(0);
assertEquals("symlink", issue.path().toString());
}

@Test
void commitWithoutSymlinkShouldPass() {
var commit = commitWithRegularFile("README.txt", "Hello, world");
var message = message(commit);
var check = new SymlinkCheck();
var issues = toList(check.check(commit, message, conf()));
assertEquals(List.of(), issues);
}
}