Update to Piston 0.5.2 + Doctools/Deprecation improvements (#523)

* Update to Piston 0.5.2

* [Doctools] Fix output, be verbose about deprecations

* Improve deprecation system, doctools output

(cherry picked from commit 03c0cce53e)
This commit is contained in:
Kenzie Togami
2019-10-05 05:06:18 -04:00
committed by MattBDev
parent 3431bd0644
commit 0767f56711
9 changed files with 303 additions and 64 deletions

View File

@ -19,30 +19,147 @@
package com.sk89q.worldedit.internal.command;
import static com.google.common.base.Preconditions.checkState;
import static java.util.stream.Collectors.toList;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.PlatformCommandManager;
import com.sk89q.worldedit.internal.util.Substring;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import org.enginehub.piston.Command;
import org.enginehub.piston.exception.CommandException;
import org.enginehub.piston.inject.InjectedValueAccess;
import org.enginehub.piston.inject.Key;
import org.enginehub.piston.part.SubCommandPart;
import com.sk89q.worldedit.util.formatting.text.event.ClickEvent;
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
import com.sk89q.worldedit.util.formatting.text.format.TextDecoration;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import static com.google.common.base.Preconditions.checkState;
import static java.util.stream.Collectors.toList;
import org.enginehub.piston.Command;
import org.enginehub.piston.CommandParameters;
import org.enginehub.piston.NoInputCommandParameters;
import org.enginehub.piston.exception.CommandException;
import org.enginehub.piston.inject.InjectedValueAccess;
import org.enginehub.piston.inject.Key;
import org.enginehub.piston.part.SubCommandPart;
public class CommandUtil {
private static final Component DEPRECATION_MARKER = TextComponent.of("This command is deprecated.");
private static Component makeDeprecatedFooter(String reason, Component newCommand) {
return TextComponent.builder()
.append(DEPRECATION_MARKER)
.append(" " + reason + ".")
.append(TextComponent.newline())
.append(TextComponent.of("Use ", TextColor.GOLD, TextDecoration.ITALIC))
.append(newCommand)
.append(TextComponent.of(" instead.", TextColor.GOLD, TextDecoration.ITALIC))
.build();
}
public interface NewCommandGenerator {
String newCommand(Command oldCommand, CommandParameters oldParameters);
}
public static Command deprecate(Command command, String reason,
NewCommandGenerator newCommandGenerator) {
Component deprecatedWarning = makeDeprecatedFooter(
reason,
newCommandSuggestion(newCommandGenerator,
NoInputCommandParameters.builder().build(),
command)
);
return command.toBuilder()
.action(parameters ->
deprecatedCommandWarning(parameters, command, reason, newCommandGenerator))
.footer(command.getFooter()
.map(existingFooter -> existingFooter
.append(TextComponent.newline()).append(deprecatedWarning))
.orElse(deprecatedWarning))
.build();
}
public static Optional<Component> footerWithoutDeprecation(Command command) {
return command.getFooter()
.filter(footer -> anyComponent(footer, Predicate.isEqual(DEPRECATION_MARKER)))
.map(footer -> Optional.of(
replaceDeprecation(footer)
))
.orElseGet(command::getFooter);
}
public static Optional<Component> deprecationWarning(Command command) {
return command.getFooter()
.map(CommandUtil::extractDeprecation)
.orElseGet(command::getFooter);
}
public static boolean isDeprecated(Command command) {
return command.getFooter()
.filter(footer -> anyComponent(footer, Predicate.isEqual(DEPRECATION_MARKER)))
.isPresent();
}
private static boolean anyComponent(Component component, Predicate<Component> test) {
return test.test(component) || component.children().stream()
.anyMatch(x -> anyComponent(x, test));
}
private static Component replaceDeprecation(Component component) {
if (component.children().stream().anyMatch(Predicate.isEqual(DEPRECATION_MARKER))) {
return TextComponent.empty();
}
return component.children(
component.children().stream()
.map(CommandUtil::replaceDeprecation)
.collect(toList())
);
}
private static Optional<Component> extractDeprecation(Component component) {
if (component.children().stream().anyMatch(Predicate.isEqual(DEPRECATION_MARKER))) {
return Optional.of(component);
}
return component.children().stream()
.map(CommandUtil::extractDeprecation)
.filter(Optional::isPresent)
.map(Optional::get)
.findAny();
}
private static int deprecatedCommandWarning(
CommandParameters parameters,
Command command,
String reason,
NewCommandGenerator generator
) throws Exception {
parameters.injectedValue(Key.of(Actor.class))
.ifPresent(actor -> {
Component suggestion = newCommandSuggestion(generator, parameters, command);
actor.print(TextComponent.of(reason + ". Please use ", TextColor.GOLD)
.append(suggestion)
.append(TextComponent.of(" instead."))
);
});
return command.getAction().run(parameters);
}
private static Component newCommandSuggestion(NewCommandGenerator generator,
CommandParameters parameters,
Command command) {
String suggestedCommand = generator.newCommand(command, parameters);
return TextComponent.of(suggestedCommand)
.decoration(TextDecoration.UNDERLINED, true)
.clickEvent(ClickEvent.suggestCommand(suggestedCommand));
}
public static Map<String, Command> getSubCommands(Command currentCommand) {
return currentCommand.getParts().stream()
.filter(p -> p instanceof SubCommandPart)