Skip to content

Commit

Permalink
Snoopin time
Browse files Browse the repository at this point in the history
  • Loading branch information
mbax committed Jul 13, 2021
0 parents commit f6b5e08
Show file tree
Hide file tree
Showing 9 changed files with 1,699 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# This is a simple .gitignore for simple needs.

# To ignore files system-wide, use the global git setting core.excludesfile
# For repo-specific ignoring, use .git/info/exclude
# To ignore the opinions of others, cover your ears and scream "LA LA LA!"

# Maven makes this!
/target
674 changes: 674 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

15 changes: 15 additions & 0 deletions LICENSE_FILE_HEADER
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
SuperLooperSnooper
Copyright (C) 2021 Matt Baxter

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program 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 for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
SuperLooperSnooper
==================

A simple Paper plugin to find dependency loops. Outputs findings after startup.
181 changes: 181 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>org.kitteh</groupId>
<artifactId>superloopersnooper</artifactId>
<version>1.0</version>
<packaging>jar</packaging>

<name>SuperLooperSnooper</name>
<description>Finds cyclical dependency issues</description>
<url>https://kitteh.org</url>

<developers>
<developer>
<id>mbaxter</id>
<name>Matt Baxter</name>
<email>[email protected]</email>
<url>https://kitteh.org</url>
<organization>Kitteh</organization>
<organizationUrl>https://kitteh.org</organizationUrl>
<roles>
<role>Lead Developer</role>
<role>Cat Wrangler</role>
</roles>
</developer>
</developers>

<licenses>
<license>
<name>GNU General Public License (GPL) version 3</name>
<url>https://www.gnu.org/licenses/gpl-3.0.txt</url>
</license>
</licenses>

<issueManagement>
<system>GitHub</system>
<url>https://github.com/KittehOrg/SuperLooperSnooper/issues</url>
</issueManagement>

<scm>
<connection>scm:git:[email protected]:KittehOrg/SuperLooperSnooper.git</connection>
<developerConnection>scm:git:[email protected]:KittehOrg/SuperLooperSnooper.git</developerConnection>
<url>[email protected]:KittehOrg/SuperLooperSnooper.git</url>
</scm>

<properties>
<java.version>16</java.version>
<jgrapht.version>1.5.1</jgrapht.version> <!-- Don't forget to check what Guava version it uses -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<repositories>
<repository>
<id>papermc-repo</id>
<url>https://papermc.io/repo/repository/maven-public/</url>
</repository>
</repositories>

<dependencies>
<dependency>
<groupId>io.papermc.paper</groupId>
<artifactId>paper-api</artifactId>
<version>1.17-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jgrapht</groupId>
<artifactId>jgrapht-core</artifactId>
<version>${jgrapht.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.jgrapht</groupId>
<artifactId>jgrapht-guava</artifactId>
<version>${jgrapht.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>29.0-jre</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<groupId>org.checkerframework</groupId>
<artifactId>checker-qual</artifactId>
</exclusion>
<exclusion>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>

<build>
<finalName>${project.name}</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<release>${java.version}</release>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.3.0-SNAPSHOT</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/MANIFEST.MF</exclude>
</excludes>
</filter>
</filters>
<relocations>
<relocation>
<pattern>com.google</pattern>
<shadedPattern>org.kitteh.superloopersnooperlibs.com.google</shadedPattern>
</relocation>
<relocation>
<pattern>org.jgrapht</pattern>
<shadedPattern>org.kitteh.superloopersnooperlibs.org.jgrapht</shadedPattern>
</relocation>
<relocation>
<pattern>org.jheaps</pattern>
<shadedPattern>org.kitteh.superloopersnooperlibs.org.jheaps</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.mycila</groupId>
<artifactId>license-maven-plugin</artifactId>
<version>3.0</version>
<executions>
<execution>
<phase>clean</phase>
<goals>
<goal>format</goal>
</goals>
</execution>
</executions>
<configuration>
<quiet>true</quiet>
<encoding>UTF-8</encoding>
<strictCheck>true</strictCheck>
<header>${basedir}/LICENSE_FILE_HEADER</header>
<mapping>
<java>SLASHSTAR_STYLE</java>
</mapping>
<includes>
<include>src/main/java/org/kitteh/**</include>
</includes>
</configuration>
</plugin>
</plugins>
</build>
</project>
106 changes: 106 additions & 0 deletions src/main/java/org/kitteh/superloopersnooper/SuperLooperSnooper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
* SuperLooperSnooper
* Copyright (C) 2021 Matt Baxter
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.kitteh.superloopersnooper;

import com.google.common.graph.GraphBuilder;
import com.google.common.graph.MutableGraph;
import org.bukkit.plugin.SimplePluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;
import org.jgrapht.alg.cycle.JohnsonSimpleCycles;
import org.jgrapht.graph.guava.MutableGraphAdapter;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;

public final class SuperLooperSnooper extends JavaPlugin {
private List<List<String>> cycles;
private Exception exception;

@Override
public void onLoad() {
try {
this.cycles = this.whee();
} catch (Exception e) {
this.exception = e;
}
}

@SuppressWarnings({"UnstableApiUsage", "unchecked"})
private List<List<String>> whee() throws Exception {
// Get original graph.
// We need to convert to a newer guava, so this is all done via reflection
// and the newer guava is relocated
Field graphField = SimplePluginManager.class.getDeclaredField("dependencyGraph");
graphField.setAccessible(true);
Object originalGraph = graphField.get(this.getServer().getPluginManager());

// Get nodes
Method methodNodes = originalGraph.getClass().getMethod("nodes");
methodNodes.setAccessible(true);
Set<String> nodes = (Set<String>) methodNodes.invoke(originalGraph);

// Successors method
Method methodSuccessors = originalGraph.getClass().getMethod("successors", Object.class);
methodSuccessors.setAccessible(true);

// New graph
MutableGraph<String> graph = GraphBuilder.directed().build();

// New edges!
for (String node : nodes) {
Set<String> successors = (Set<String>) methodSuccessors.invoke(originalGraph, node);
for (String successor : successors) {
graph.putEdge(node, successor);
}
}

return new JohnsonSimpleCycles<>(new MutableGraphAdapter<>(graph)).findSimpleCycles();
}

@Override
public void onEnable() {
new BukkitRunnable() {
@Override
public void run() {
boolean ex = SuperLooperSnooper.this.exception != null;
boolean empty = SuperLooperSnooper.this.cycles == null || SuperLooperSnooper.this.cycles.isEmpty();
Level level = (empty && !ex) ? Level.INFO : Level.SEVERE;
SuperLooperSnooper.this.getLogger().log(level, "");
SuperLooperSnooper.this.getLogger().log(level, "Hello! I'm here to snoop for loops!");
SuperLooperSnooper.this.getLogger().log(level, "");
if (ex) {
SuperLooperSnooper.this.getLogger().log(Level.SEVERE, " Unfortunately, I instead encountered an error!\n", SuperLooperSnooper.this.exception);
return;
}
if (empty) {
SuperLooperSnooper.this.getLogger().log(level, "Found no dependency loops! Yay!");
return;
}
SuperLooperSnooper.this.getLogger().log(level, " Found dependency loops:");
for (List<String> list : SuperLooperSnooper.this.cycles) {
SuperLooperSnooper.this.getLogger().log(level, " " + list);
}
SuperLooperSnooper.this.getLogger().log(level, "");
}
}.runTaskLater(this, 40L);
}
}
29 changes: 29 additions & 0 deletions src/main/resources/credit.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
This plugin contains the following:

JGraphT - https://github.com/jgrapht/jgrapht
Licensed under the terms of the GNU Lesser General Public License (LGPL) 2.1 http://www.gnu.org/licenses/lgpl-2.1.html

JHeaps - https://github.com/d-michail/jheaps
Licensed under the terms of the Apache License 2.0 https://www.apache.org/licenses/LICENSE-2.0

Guava - https://github.com/google/guava
Licensed under the terms of the Apache License 2.0 https://www.apache.org/licenses/LICENSE-2.0


This combined jar operates under the following terms:

SuperLooperSnooper
Copyright (C) 2021 Matt Baxter

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program 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 for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Loading

0 comments on commit f6b5e08

Please sign in to comment.