Create tag template / auto-generate page for all permissions incl. description

This commit is contained in:
ljacqu
2015-12-05 20:53:44 +01:00
parent c91fb46951
commit 4d082388a5
13 changed files with 261 additions and 114 deletions
@@ -0,0 +1,113 @@
package permissions;
import fr.xephi.authme.permission.AdminPermission;
import fr.xephi.authme.permission.PermissionNode;
import fr.xephi.authme.permission.PlayerPermission;
import fr.xephi.authme.util.StringUtils;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Gatherer to generate up-to-date lists of the AuthMe permission nodes.
*/
public class PermissionNodesGatherer {
/** The folder in which the implementations of {@link PermissionNode} reside. */
private static final String PERMISSION_NODE_SOURCE_FOLDER =
"src/main/java/fr/xephi/authme/permission/";
/**
* Regular expression that should match the JavaDoc comment above an enum, <i>including</i>
* the name of the enum value. The first group (i.e. {@code \\1}) should be the JavaDoc description;
* the second group should contain the enum value.
*/
private static final Pattern JAVADOC_WITH_ENUM_PATTERN = Pattern.compile(
"/\\*\\*\\s+\\*" // Match starting '/**' and the '*' on the next line
+ "(.*?)\\s+\\*/" // Capture everything until we encounter '*/'
+ "\\s+([A-Z_]+)\\("); // Match the enum name (e.g. 'LOGIN'), until before the first '('
/**
* Return a sorted collection of all permission nodes.
*
* @return AuthMe permission nodes sorted alphabetically
*/
public Set<String> gatherNodes() {
Set<String> nodes = new TreeSet<>();
for (PermissionNode perm : PlayerPermission.values()) {
nodes.add(perm.getNode());
}
for (PermissionNode perm : AdminPermission.values()) {
nodes.add(perm.getNode());
}
return nodes;
}
/**
* Return a sorted collection of all permission nodes, including its JavaDoc description.
*
* @return Ordered map whose keys are the permission nodes and the values the associated JavaDoc
*/
public Map<String, String> gatherNodesWithJavaDoc() {
Map<String, String> result = new TreeMap<>();
addDescriptionsForClass(PlayerPermission.class, result);
addDescriptionsForClass(AdminPermission.class, result);
return result;
}
private <T extends Enum<T> & PermissionNode> void addDescriptionsForClass(Class<T> clazz,
Map<String, String> descriptions) {
String classSource = getSourceForClass(clazz);
Map<String, String> sourceDescriptions = extractJavaDocFromSource(classSource);
for (T perm : EnumSet.allOf(clazz)) {
String description = sourceDescriptions.get(perm.name());
if (description == null) {
System.out.println("Note: Could not retrieve description for "
+ clazz.getSimpleName() + "#" + perm.name());
description = "";
}
descriptions.put(perm.getNode(), description.trim());
}
}
private static Map<String, String> extractJavaDocFromSource(String source) {
Map<String, String> allMatches = new HashMap<>();
Matcher matcher = JAVADOC_WITH_ENUM_PATTERN.matcher(source);
while (matcher.find()) {
String description = matcher.group(1);
String enumValue = matcher.group(2);
allMatches.put(enumValue, description);
}
return allMatches;
}
/**
* Return the Java source code for the given implementation of {@link PermissionNode}.
*
* @param clazz The clazz to the get the source for
* @param <T> The concrete class
* @return Source code of the file
*/
private static <T extends Enum<T> & PermissionNode> String getSourceForClass(Class<T> clazz) {
String classFile = PERMISSION_NODE_SOURCE_FOLDER + clazz.getSimpleName() + ".java";
Charset cs = Charset.forName("utf-8");
try {
return StringUtils.join("\n",
Files.readAllLines(Paths.get(classFile), cs));
} catch (IOException e) {
throw new RuntimeException("Failed to get the source for class '" + clazz.getSimpleName() + "'");
}
}
}
@@ -0,0 +1,86 @@
package permissions;
import utils.ANewMap;
import utils.GeneratedFileWriter;
import utils.TagReplacer;
import utils.ToolsConstants;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
/**
* Class responsible for formatting a permissions node list and
* for writing it to a file if desired.
*/
public class PermissionsListWriter {
private static final String PERMISSIONS_OUTPUT_FILE = ToolsConstants.DOCS_FOLDER + "permission_nodes.md";
public static void main(String[] args) {
// Ask if result should be written to file
Scanner scanner = new Scanner(System.in);
System.out.println("Include description? [Enter 'n' for no]");
boolean includeDescription = !matches("n", scanner);
if (!includeDescription) {
outputSimpleList();
return;
}
System.out.println("Write to file? [Enter 'n' for console output]");
boolean writeToFile = !matches("n", scanner);
scanner.close();
if (writeToFile) {
generateAndWriteFile();
} else {
System.out.println(generatePermissionsList());
}
}
private static void generateAndWriteFile() {
final String permissionsTagValue = generatePermissionsList();
Map<String, Object> tags = ANewMap.<String, Object>with("permissions", permissionsTagValue).build();
GeneratedFileWriter.generateFileFromTemplate(
ToolsConstants.TOOLS_SOURCE_ROOT + "permissions/permission_nodes.tpl.md", PERMISSIONS_OUTPUT_FILE, tags);
System.out.println("Wrote to '" + PERMISSIONS_OUTPUT_FILE + "'");
System.out.println("Before committing, please verify the output!");
}
private static String generatePermissionsList() {
PermissionNodesGatherer gatherer = new PermissionNodesGatherer();
Map<String, String> permissions = gatherer.gatherNodesWithJavaDoc();
final String template = GeneratedFileWriter.readFromToolsFile("permissions/permission_node_entry.tpl.md");
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> entry : permissions.entrySet()) {
Map<String, Object> tags = ANewMap.<String, Object>
with("node", entry.getKey())
.and("description", entry.getValue())
.build();
sb.append(TagReplacer.applyReplacements(template, tags));
}
return sb.toString();
}
private static void outputSimpleList() {
PermissionNodesGatherer gatherer = new PermissionNodesGatherer();
Set<String> nodes = gatherer.gatherNodes();
for (String node : nodes) {
System.out.println(node);
}
System.out.println();
System.out.println("Total: " + nodes.size());
}
private static boolean matches(String answer, Scanner sc) {
String userInput = sc.nextLine();
return answer.equalsIgnoreCase(userInput);
}
}
+2
View File
@@ -0,0 +1,2 @@
# About
Helper script to generate a page with an up-to-date list of permission nodes.
@@ -0,0 +1 @@
- **{node}** {description}
@@ -0,0 +1,7 @@
<!-- {gen_warning} -->
<!-- File auto-generated on {gen_date}. See permissions/permission_nodes.tpl.md -->
## AuthMe Permission Nodes
The following are the permission nodes that are currently supported by the latest dev builds.
{permissions}