Merge pull request #18942 from jimferenczi/did_you_mean_plugin
Add did-you-mean for plugin cli
This commit is contained in:
commit
d72e79159e
|
@ -45,11 +45,14 @@ import java.util.Map;
|
|||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
import joptsimple.OptionSet;
|
||||
import joptsimple.OptionSpec;
|
||||
import org.apache.lucene.search.spell.LevensteinDistance;
|
||||
import org.apache.lucene.util.CollectionUtil;
|
||||
import org.apache.lucene.util.IOUtils;
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.bootstrap.JarHell;
|
||||
|
@ -57,6 +60,7 @@ import org.elasticsearch.cli.ExitCodes;
|
|||
import org.elasticsearch.cli.SettingCommand;
|
||||
import org.elasticsearch.cli.Terminal;
|
||||
import org.elasticsearch.cli.UserError;
|
||||
import org.elasticsearch.common.collect.Tuple;
|
||||
import org.elasticsearch.common.hash.MessageDigests;
|
||||
import org.elasticsearch.common.io.FileSystemUtils;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
|
@ -239,12 +243,31 @@ class InstallPluginCommand extends SettingCommand {
|
|||
// fall back to plain old URL
|
||||
if (pluginId.contains(":/") == false) {
|
||||
// definitely not a valid url, so assume it is a plugin name
|
||||
throw new UserError(ExitCodes.USAGE, "Unknown plugin " + pluginId);
|
||||
List<String> plugins = checkMisspelledPlugin(pluginId);
|
||||
String msg = "Unknown plugin " + pluginId;
|
||||
if (plugins.isEmpty() == false) {
|
||||
msg += ", did you mean " + (plugins.size() == 1 ? "[" + plugins.get(0) + "]": "any of " + plugins.toString()) + "?";
|
||||
}
|
||||
throw new UserError(ExitCodes.USAGE, msg);
|
||||
}
|
||||
terminal.println("-> Downloading " + URLDecoder.decode(pluginId, "UTF-8"));
|
||||
return downloadZip(terminal, pluginId, tmpDir);
|
||||
}
|
||||
|
||||
/** Returns all the official plugin names that look similar to pluginId. **/
|
||||
private List<String> checkMisspelledPlugin(String pluginId) {
|
||||
LevensteinDistance ld = new LevensteinDistance();
|
||||
List<Tuple<Float, String>> scoredKeys = new ArrayList<>();
|
||||
for (String officialPlugin : OFFICIAL_PLUGINS) {
|
||||
float distance = ld.getDistance(pluginId, officialPlugin);
|
||||
if (distance > 0.7f) {
|
||||
scoredKeys.add(new Tuple<>(distance, officialPlugin));
|
||||
}
|
||||
}
|
||||
CollectionUtil.timSort(scoredKeys, (a, b) -> b.v1().compareTo(a.v1()));
|
||||
return scoredKeys.stream().map((a) -> a.v2()).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/** Downloads a zip from the url, into a temp file under the given temp dir. */
|
||||
private Path downloadZip(Terminal terminal, String urlString, Path tmpDir) throws IOException {
|
||||
terminal.println(VERBOSE, "Retrieving zip from " + urlString);
|
||||
|
|
|
@ -67,6 +67,7 @@ import java.util.stream.Collectors;
|
|||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||
|
||||
|
@ -567,6 +568,21 @@ public class InstallPluginCommandTests extends ESTestCase {
|
|||
assertTrue(terminal.getOutput(), terminal.getOutput().contains("x-pack"));
|
||||
}
|
||||
|
||||
public void testInstallMisspelledOfficialPlugins() throws Exception {
|
||||
Tuple<Path, Environment> env = createEnv(fs, temp);
|
||||
UserError e = expectThrows(UserError.class, () -> installPlugin("xpack", env.v1()));
|
||||
assertThat(e.getMessage(), containsString("Unknown plugin xpack, did you mean [x-pack]?"));
|
||||
|
||||
e = expectThrows(UserError.class, () -> installPlugin("analysis-smartnc", env.v1()));
|
||||
assertThat(e.getMessage(), containsString("Unknown plugin analysis-smartnc, did you mean [analysis-smartcn]?"));
|
||||
|
||||
e = expectThrows(UserError.class, () -> installPlugin("repository", env.v1()));
|
||||
assertThat(e.getMessage(), containsString("Unknown plugin repository, did you mean any of [repository-s3, repository-gcs]?"));
|
||||
|
||||
e = expectThrows(UserError.class, () -> installPlugin("unknown_plugin", env.v1()));
|
||||
assertThat(e.getMessage(), containsString("Unknown plugin unknown_plugin"));
|
||||
}
|
||||
|
||||
// TODO: test batch flag?
|
||||
// TODO: test checksum (need maven/official below)
|
||||
// TODO: test maven, official, and staging install...need tests with fixtures...
|
||||
|
|
Loading…
Reference in New Issue