From 789c6638c9fae1741d1e84cc14e3049f52eb725c Mon Sep 17 00:00:00 2001 From: Michael Dowling Date: Wed, 5 Apr 2023 20:47:52 -0700 Subject: [PATCH 1/2] Add example of how we could launch the LSP in CLI WIP example that we could use the CLI to download and launch the LSP rather than need to rely on installing an entire JRE and use Coursier. --- .../smithy/cli/commands/JavaHelper.java | 56 +++++++++ .../smithy/cli/commands/LspCommand.java | 110 ++++++++++++++++++ .../smithy/cli/commands/SmithyCommand.java | 1 + .../smithy/cli/commands/WarmupCommand.java | 20 +--- .../dependencies/MavenDependencyResolver.java | 9 +- .../MavenDependencyResolverTest.java | 1 - 6 files changed, 176 insertions(+), 21 deletions(-) create mode 100644 smithy-cli/src/main/java/software/amazon/smithy/cli/commands/JavaHelper.java create mode 100644 smithy-cli/src/main/java/software/amazon/smithy/cli/commands/LspCommand.java diff --git a/smithy-cli/src/main/java/software/amazon/smithy/cli/commands/JavaHelper.java b/smithy-cli/src/main/java/software/amazon/smithy/cli/commands/JavaHelper.java new file mode 100644 index 00000000000..42262daaa61 --- /dev/null +++ b/smithy-cli/src/main/java/software/amazon/smithy/cli/commands/JavaHelper.java @@ -0,0 +1,56 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package software.amazon.smithy.cli.commands; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import software.amazon.smithy.cli.CliError; +import software.amazon.smithy.utils.StringUtils; + +final class JavaHelper { + + private JavaHelper() {} + + static Path getJavaHome() { + return Paths.get(getOrThrowIfUndefinedProperty("java.home")); + } + + static Path getJavaBinary() { + Path javaHome = getJavaHome(); + Path bin = javaHome.resolve("bin"); + Path windowsBinary = bin.resolve("java.exe"); + Path posixBinary = bin.resolve("java"); + + if (!Files.isDirectory(bin)) { + throw new CliError("$JAVA_HOME/bin directory not found: " + bin); + } else if (Files.exists(windowsBinary)) { + return windowsBinary; + } else if (Files.exists(posixBinary)) { + return posixBinary; + } else { + throw new CliError("No java binary found in " + bin); + } + } + + private static String getOrThrowIfUndefinedProperty(String property) { + String result = System.getProperty(property); + if (StringUtils.isEmpty(result)) { + throw new CliError(result + " system property is not defined"); + } + return result; + } +} diff --git a/smithy-cli/src/main/java/software/amazon/smithy/cli/commands/LspCommand.java b/smithy-cli/src/main/java/software/amazon/smithy/cli/commands/LspCommand.java new file mode 100644 index 00000000000..61eec533b47 --- /dev/null +++ b/smithy-cli/src/main/java/software/amazon/smithy/cli/commands/LspCommand.java @@ -0,0 +1,110 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package software.amazon.smithy.cli.commands; + +import java.io.IOException; +import java.util.List; +import java.util.function.Consumer; +import software.amazon.smithy.build.model.MavenRepository; +import software.amazon.smithy.build.model.SmithyBuildConfig; +import software.amazon.smithy.cli.ArgumentReceiver; +import software.amazon.smithy.cli.Arguments; +import software.amazon.smithy.cli.Command; +import software.amazon.smithy.cli.HelpPrinter; +import software.amazon.smithy.cli.StandardOptions; +import software.amazon.smithy.cli.dependencies.DependencyResolver; +import software.amazon.smithy.cli.dependencies.ResolvedArtifact; +import software.amazon.smithy.utils.ListUtils; + +final class LspCommand implements Command { + + private final String parentCommandName; + private final DependencyResolver.Factory dependencyResolverFactory; + + LspCommand(String parentCommandName, DependencyResolver.Factory dependencyResolverFactory) { + this.parentCommandName = parentCommandName; + this.dependencyResolverFactory = dependencyResolverFactory; + } + + private static final class Options implements ArgumentReceiver { + private String version = "LATEST"; + + @Override + public Consumer testParameter(String name) { + if ("--version".equals(name)) { + return v -> version = v; + } + return null; + } + + @Override + public void registerHelp(HelpPrinter printer) { + printer.param("--version", null, "LSP_VERSION", + "Provides a custom LSP version. Uses the latest version by default."); + } + } + + @Override + public String getName() { + return "lsp"; + } + + @Override + public String getSummary() { + return "Downloads, starts, and stops the Smithy Language Server Protocol (LSP)."; + } + + @Override + public int execute(Arguments arguments, Env env) { + arguments.addReceiver(new ConfigOptions()); + arguments.addReceiver(new Options()); + + CommandAction action = HelpActionWrapper.fromCommand( + this, parentCommandName, this::runLsp); + + return action.apply(arguments, env); + } + + private int runLsp(Arguments arguments, Env env) { + StandardOptions standardOptions = arguments.getReceiver(StandardOptions.class); + ConfigOptions configOptions = arguments.getReceiver(ConfigOptions.class); + SmithyBuildConfig config = configOptions.createSmithyBuildConfig(); + DependencyResolver resolver = dependencyResolverFactory.create(config, env); + Options options = arguments.getReceiver(Options.class); + + if (!standardOptions.quiet()) { + env.stderr().println("Checking for and possibly downloading LSP"); + env.stderr().flush(); + } + + resolver.addRepository(MavenRepository.builder().url("https://repo.maven.apache.org/maven2").build()); + resolver.addDependency("software.amazon.smithy:smithy-language-server:" + options.version); + List resolvedArtifacts = resolver.resolve(); + + if (!standardOptions.quiet()) { + env.stderr().println("Starting LSP at version: " + resolvedArtifacts.get(0).getVersion()); + env.stderr().flush(); + } + + String javaBinary = JavaHelper.getJavaBinary().toString(); + List args = ListUtils.of(javaBinary, "-jar", resolvedArtifacts.get(0).getPath().toString(), "0"); + try { + return new ProcessBuilder(args).inheritIO().start().waitFor(); + } catch (InterruptedException | IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/smithy-cli/src/main/java/software/amazon/smithy/cli/commands/SmithyCommand.java b/smithy-cli/src/main/java/software/amazon/smithy/cli/commands/SmithyCommand.java index 167615aa1e4..ae78346be4e 100644 --- a/smithy-cli/src/main/java/software/amazon/smithy/cli/commands/SmithyCommand.java +++ b/smithy-cli/src/main/java/software/amazon/smithy/cli/commands/SmithyCommand.java @@ -47,6 +47,7 @@ public SmithyCommand(DependencyResolver.Factory dependencyResolverFactory) { new AstCommand(getName(), dependencyResolverFactory), new SelectCommand(getName(), dependencyResolverFactory), new CleanCommand(getName()), + new LspCommand(getName(), dependencyResolverFactory), migrateCommand, deprecated1To2Command, new WarmupCommand(getName()) diff --git a/smithy-cli/src/main/java/software/amazon/smithy/cli/commands/WarmupCommand.java b/smithy-cli/src/main/java/software/amazon/smithy/cli/commands/WarmupCommand.java index 4923e0c29d4..87de28ca073 100644 --- a/smithy-cli/src/main/java/software/amazon/smithy/cli/commands/WarmupCommand.java +++ b/smithy-cli/src/main/java/software/amazon/smithy/cli/commands/WarmupCommand.java @@ -20,7 +20,6 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -105,13 +104,10 @@ private int run(Arguments arguments, Env env) { } private int orchestrate(boolean isDebug, CliPrinter printer) { - List baseArgs = new ArrayList<>(); String classpath = getOrThrowIfUndefinedProperty("java.class.path"); - Path javaHome = Paths.get(getOrThrowIfUndefinedProperty("java.home")); + Path javaHome = JavaHelper.getJavaHome(); + Path javaBinary = JavaHelper.getJavaBinary(); Path lib = javaHome.resolve("lib"); - Path bin = javaHome.resolve("bin"); - Path windowsBinary = bin.resolve("java.exe"); - Path posixBinary = bin.resolve("java"); Path jsaFile = lib.resolve("smithy.jsa"); Path classListFile = lib.resolve("classlist"); @@ -119,16 +115,8 @@ private int orchestrate(boolean isDebug, CliPrinter printer) { classListFile.toFile().delete(); jsaFile.toFile().delete(); - if (!Files.isDirectory(bin)) { - throw new CliError("$JAVA_HOME/bin directory not found: " + bin); - } else if (Files.exists(windowsBinary)) { - baseArgs.add(windowsBinary.toString()); - } else if (Files.exists(posixBinary)) { - baseArgs.add(posixBinary.toString()); - } else { - throw new CliError("No java binary found in " + bin); - } - + List baseArgs = new ArrayList<>(); + baseArgs.add(javaBinary.toString()); baseArgs.add("-classpath"); baseArgs.add(classpath); diff --git a/smithy-cli/src/main/java/software/amazon/smithy/cli/dependencies/MavenDependencyResolver.java b/smithy-cli/src/main/java/software/amazon/smithy/cli/dependencies/MavenDependencyResolver.java index 95c49e07739..a0aabc2920c 100644 --- a/smithy-cli/src/main/java/software/amazon/smithy/cli/dependencies/MavenDependencyResolver.java +++ b/smithy-cli/src/main/java/software/amazon/smithy/cli/dependencies/MavenDependencyResolver.java @@ -161,10 +161,11 @@ private static Dependency createDependency(String coordinates, String scope) { private static void validateDependencyVersion(Artifact artifact) { String version = artifact.getVersion(); - if (version.equals("LATEST")) { - throw new DependencyResolverException("LATEST dependencies are not supported: " + artifact); - } else if (version.equals("latest-status") || version.startsWith("latest.")) { - throw new DependencyResolverException("Gradle style latest dependencies are not supported: " + artifact); + if (version.equals("latest.release")) { + // Change latest.release to LATEST. + artifact.setVersion("LATEST"); + } else if (version.equals("latest-status")) { + throw new DependencyResolverException("latest-status is not supported: " + artifact); } else if (version.equals("RELEASE")) { throw new DependencyResolverException("RELEASE dependencies are not supported: " + artifact); } else if (version.contains("+")) { diff --git a/smithy-cli/src/test/java/software/amazon/smithy/cli/dependencies/MavenDependencyResolverTest.java b/smithy-cli/src/test/java/software/amazon/smithy/cli/dependencies/MavenDependencyResolverTest.java index c618d1af2b4..eb3408c112b 100644 --- a/smithy-cli/src/test/java/software/amazon/smithy/cli/dependencies/MavenDependencyResolverTest.java +++ b/smithy-cli/src/test/java/software/amazon/smithy/cli/dependencies/MavenDependencyResolverTest.java @@ -39,7 +39,6 @@ public static Stream invalidDependencies() { Arguments.of("smithy.foo:bar:1.25.0-SNAPSHOT"), Arguments.of("smithy.foo:bar:RELEASE"), Arguments.of("smithy.foo:bar:latest-status"), - Arguments.of("smithy.foo:bar:LATEST"), Arguments.of("smithy.foo:bar:1.25.0+"), Arguments.of("a::1.2.0"), Arguments.of(":b:1.2.0"), From 7f520edab6f9511f8387531787939f5796fa92fc Mon Sep 17 00:00:00 2001 From: Michael Dowling Date: Thu, 6 Apr 2023 20:28:46 -0700 Subject: [PATCH 2/2] Add WIP support for LSP and format commands --- config/spotbugs/filter.xml | 4 + .../smithy/cli/commands/ClasspathAction.java | 25 +--- .../smithy/cli/commands/DependencyHelper.java | 58 +++++++++ .../smithy/cli/commands/FormatCommand.java | 121 ++++++++++++++++++ .../smithy/cli/commands/LspCommand.java | 37 +++--- .../smithy/cli/commands/ModelBuilder.java | 4 +- .../smithy/cli/commands/SmithyCommand.java | 1 + .../smithy/cli/commands/StyleHelper.java | 1 + 8 files changed, 209 insertions(+), 42 deletions(-) create mode 100644 smithy-cli/src/main/java/software/amazon/smithy/cli/commands/DependencyHelper.java create mode 100644 smithy-cli/src/main/java/software/amazon/smithy/cli/commands/FormatCommand.java diff --git a/config/spotbugs/filter.xml b/config/spotbugs/filter.xml index 24d313006d0..23aacb80283 100644 --- a/config/spotbugs/filter.xml +++ b/config/spotbugs/filter.xml @@ -158,6 +158,10 @@ + + + + diff --git a/smithy-cli/src/main/java/software/amazon/smithy/cli/commands/ClasspathAction.java b/smithy-cli/src/main/java/software/amazon/smithy/cli/commands/ClasspathAction.java index 75bf97a0ff7..92a69df8a27 100644 --- a/smithy-cli/src/main/java/software/amazon/smithy/cli/commands/ClasspathAction.java +++ b/smithy-cli/src/main/java/software/amazon/smithy/cli/commands/ClasspathAction.java @@ -135,7 +135,7 @@ private List resolveDependencies( DependencyResolver resolver = new FileCacheResolver(getCacheFile(buildOptions, smithyBuildConfig), lastModified, delegate); - addConfiguredMavenRepos(smithyBuildConfig, resolver); + DependencyHelper.addConfiguredMavenRepos(smithyBuildConfig, resolver); maven.getDependencies().forEach(resolver::addDependency); List artifacts = resolver.resolve(); LOGGER.fine(() -> "Classpath resolved with Maven: " + artifacts); @@ -148,29 +148,6 @@ private List resolveDependencies( return result; } - private static void addConfiguredMavenRepos(SmithyBuildConfig config, DependencyResolver resolver) { - // Environment variables take precedence over config files. - String envRepos = EnvironmentVariable.SMITHY_MAVEN_REPOS.get(); - if (envRepos != null) { - for (String repo : envRepos.split("\\|")) { - resolver.addRepository(MavenRepository.builder().url(repo.trim()).build()); - } - } - - Set configuredRepos = config.getMaven() - .map(MavenConfig::getRepositories) - .orElse(Collections.emptySet()); - - if (!configuredRepos.isEmpty()) { - configuredRepos.forEach(resolver::addRepository); - } else if (envRepos == null) { - LOGGER.finest(() -> String.format("maven.repositories is not defined in smithy-build.json and the %s " - + "environment variable is not set. Defaulting to Maven Central.", - EnvironmentVariable.SMITHY_MAVEN_REPOS)); - resolver.addRepository(CENTRAL); - } - } - private File getCacheFile(BuildOptions buildOptions, SmithyBuildConfig config) { return buildOptions.resolveOutput(config).resolve("classpath.json").toFile(); } diff --git a/smithy-cli/src/main/java/software/amazon/smithy/cli/commands/DependencyHelper.java b/smithy-cli/src/main/java/software/amazon/smithy/cli/commands/DependencyHelper.java new file mode 100644 index 00000000000..393cb6cfe79 --- /dev/null +++ b/smithy-cli/src/main/java/software/amazon/smithy/cli/commands/DependencyHelper.java @@ -0,0 +1,58 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package software.amazon.smithy.cli.commands; + +import java.util.Collections; +import java.util.Set; +import java.util.logging.Logger; +import software.amazon.smithy.build.model.MavenConfig; +import software.amazon.smithy.build.model.MavenRepository; +import software.amazon.smithy.build.model.SmithyBuildConfig; +import software.amazon.smithy.cli.EnvironmentVariable; +import software.amazon.smithy.cli.dependencies.DependencyResolver; + +final class DependencyHelper { + + private static final Logger LOGGER = Logger.getLogger(DependencyHelper.class.getName()); + private static final MavenRepository CENTRAL = MavenRepository.builder() + .url("https://repo.maven.apache.org/maven2") + .build(); + + private DependencyHelper() { } + + static void addConfiguredMavenRepos(SmithyBuildConfig config, DependencyResolver resolver) { + // Environment variables take precedence over config files. + String envRepos = EnvironmentVariable.SMITHY_MAVEN_REPOS.get(); + if (envRepos != null) { + for (String repo : envRepos.split("\\|")) { + resolver.addRepository(MavenRepository.builder().url(repo.trim()).build()); + } + } + + Set configuredRepos = config.getMaven() + .map(MavenConfig::getRepositories) + .orElse(Collections.emptySet()); + + if (!configuredRepos.isEmpty()) { + configuredRepos.forEach(resolver::addRepository); + } else if (envRepos == null) { + LOGGER.finest(() -> String.format("maven.repositories is not defined in smithy-build.json and the %s " + + "environment variable is not set. Defaulting to Maven Central.", + EnvironmentVariable.SMITHY_MAVEN_REPOS)); + resolver.addRepository(CENTRAL); + } + } +} diff --git a/smithy-cli/src/main/java/software/amazon/smithy/cli/commands/FormatCommand.java b/smithy-cli/src/main/java/software/amazon/smithy/cli/commands/FormatCommand.java new file mode 100644 index 00000000000..dc832384636 --- /dev/null +++ b/smithy-cli/src/main/java/software/amazon/smithy/cli/commands/FormatCommand.java @@ -0,0 +1,121 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package software.amazon.smithy.cli.commands; + +import java.io.FileWriter; +import java.io.PrintWriter; +import java.lang.reflect.Method; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import software.amazon.smithy.build.model.SmithyBuildConfig; +import software.amazon.smithy.cli.Arguments; +import software.amazon.smithy.cli.CliError; +import software.amazon.smithy.cli.Command; +import software.amazon.smithy.cli.StandardOptions; +import software.amazon.smithy.cli.dependencies.DependencyResolver; +import software.amazon.smithy.cli.dependencies.ResolvedArtifact; +import software.amazon.smithy.utils.IoUtils; + +final class FormatCommand implements Command { + + private final String parentCommandName; + private final DependencyResolver.Factory dependencyResolverFactory; + + FormatCommand(String parentCommandName, DependencyResolver.Factory dependencyResolverFactory) { + this.parentCommandName = parentCommandName; + this.dependencyResolverFactory = dependencyResolverFactory; + } + + @Override + public String getName() { + return "format"; + } + + @Override + public String getSummary() { + return "Formats Smithy IDL models in place."; + } + + @Override + public int execute(Arguments arguments, Env env) { + arguments.addReceiver(new ConfigOptions()); + + CommandAction action = HelpActionWrapper.fromCommand( + this, parentCommandName, this::runFormatter); + + return action.apply(arguments, env); + } + + private int runFormatter(Arguments arguments, Env env) { + StandardOptions standardOptions = arguments.getReceiver(StandardOptions.class); + ConfigOptions configOptions = arguments.getReceiver(ConfigOptions.class); + SmithyBuildConfig config = configOptions.createSmithyBuildConfig(); + DependencyResolver resolver = dependencyResolverFactory.create(config, env); + + if (!standardOptions.quiet()) { + env.stderr().append("Checking for Smithy formatter...").flush(); + } + + DependencyHelper.addConfiguredMavenRepos(config, resolver); + resolver.addDependency("software.amazon.smithy:smithy-language-server:LATEST"); + List resolvedArtifacts = resolver.resolve(); + List dependencies = new ArrayList<>(resolvedArtifacts.size()); + for (ResolvedArtifact artifact : resolvedArtifacts) { + dependencies.add(artifact.getPath()); + } + + if (env.colors().isColorEnabled()) { + env.stderr().append("\r").append(StyleHelper.CLEAR_LINE_ESCAPE).flush(); + } + + List positional = arguments.getPositional(); + if (positional.isEmpty()) { + throw new CliError("Missing required positional argument pointing to a file to format"); + } else if (positional.size() > 1) { + throw new CliError("Can only format a single model file"); + } + + String file = positional.get(0); + String contents = IoUtils.readUtf8File(file); + + new IsolatedRunnable(dependencies, getClass().getClassLoader().getParent(), loader -> { + try { + Class main = loader.loadClass("smithyfmt.Formatter"); + Method method = main.getMethod("format", String.class); + Object response = method.invoke(null, contents); + Method isSuccess = response.getClass().getMethod("isSuccess"); + if ((boolean) isSuccess.invoke(response)) { + Method valueMethod = response.getClass().getMethod("getValue"); + String formatted = (String) valueMethod.invoke(response); + FileWriter fileWriter = new FileWriter(file); + PrintWriter printWriter = new PrintWriter(fileWriter); + printWriter.print(formatted); + printWriter.close(); + } else { + Method errorMessage = response.getClass().getMethod("getError"); + throw new CliError("Error formatting model: " + errorMessage.invoke(response), 1); + } + } catch (CliError e) { + throw e; + } catch (Exception e) { + throw new CliError("Error formatting model", 1, e); + } + }).run(); + + return 0; + } +} diff --git a/smithy-cli/src/main/java/software/amazon/smithy/cli/commands/LspCommand.java b/smithy-cli/src/main/java/software/amazon/smithy/cli/commands/LspCommand.java index 61eec533b47..b5b0495f790 100644 --- a/smithy-cli/src/main/java/software/amazon/smithy/cli/commands/LspCommand.java +++ b/smithy-cli/src/main/java/software/amazon/smithy/cli/commands/LspCommand.java @@ -15,19 +15,20 @@ package software.amazon.smithy.cli.commands; -import java.io.IOException; +import java.lang.reflect.Method; +import java.nio.file.Path; +import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; -import software.amazon.smithy.build.model.MavenRepository; import software.amazon.smithy.build.model.SmithyBuildConfig; import software.amazon.smithy.cli.ArgumentReceiver; import software.amazon.smithy.cli.Arguments; +import software.amazon.smithy.cli.CliError; import software.amazon.smithy.cli.Command; import software.amazon.smithy.cli.HelpPrinter; import software.amazon.smithy.cli.StandardOptions; import software.amazon.smithy.cli.dependencies.DependencyResolver; import software.amazon.smithy.cli.dependencies.ResolvedArtifact; -import software.amazon.smithy.utils.ListUtils; final class LspCommand implements Command { @@ -86,25 +87,31 @@ private int runLsp(Arguments arguments, Env env) { Options options = arguments.getReceiver(Options.class); if (!standardOptions.quiet()) { - env.stderr().println("Checking for and possibly downloading LSP"); - env.stderr().flush(); + env.stderr().println("Checking for Smithy LSP...").flush(); } - resolver.addRepository(MavenRepository.builder().url("https://repo.maven.apache.org/maven2").build()); + DependencyHelper.addConfiguredMavenRepos(config, resolver); resolver.addDependency("software.amazon.smithy:smithy-language-server:" + options.version); List resolvedArtifacts = resolver.resolve(); + List dependencies = new ArrayList<>(resolvedArtifacts.size()); + for (ResolvedArtifact artifact : resolvedArtifacts) { + dependencies.add(artifact.getPath()); + } if (!standardOptions.quiet()) { - env.stderr().println("Starting LSP at version: " + resolvedArtifacts.get(0).getVersion()); - env.stderr().flush(); + env.stderr().println("Starting LSP at version: " + resolvedArtifacts.get(0).getVersion()).flush(); } - String javaBinary = JavaHelper.getJavaBinary().toString(); - List args = ListUtils.of(javaBinary, "-jar", resolvedArtifacts.get(0).getPath().toString(), "0"); - try { - return new ProcessBuilder(args).inheritIO().start().waitFor(); - } catch (InterruptedException | IOException e) { - throw new RuntimeException(e); - } + new IsolatedRunnable(dependencies, getClass().getClassLoader().getParent(), loader -> { + try { + Class main = loader.loadClass("software.amazon.smithy.lsp.Main"); + Method method = main.getMethod("main", String[].class); + method.invoke(null, (Object) new String[]{"0"}); + } catch (Exception e) { + throw new CliError("Error running LSP", 1, e); + } + }).run(); + + return 0; } } diff --git a/smithy-cli/src/main/java/software/amazon/smithy/cli/commands/ModelBuilder.java b/smithy-cli/src/main/java/software/amazon/smithy/cli/commands/ModelBuilder.java index b9020bee8c9..bec6fe203a0 100644 --- a/smithy-cli/src/main/java/software/amazon/smithy/cli/commands/ModelBuilder.java +++ b/smithy-cli/src/main/java/software/amazon/smithy/cli/commands/ModelBuilder.java @@ -48,7 +48,6 @@ final class ModelBuilder { private static final Logger LOGGER = Logger.getLogger(ModelBuilder.class.getName()); - private static final String CLEAR_LINE_ESCAPE = "\033[2K\r"; private static final int DEFAULT_CODE_LINES = 6; private Validator.Mode validationMode; @@ -217,8 +216,7 @@ static Consumer createStatusUpdater( // If a status update was printed, then clear it out. static void clearStatusUpdateIfPresent(AtomicInteger issueCount, CliPrinter stderr) { if (issueCount.get() > 0) { - stderr.append(CLEAR_LINE_ESCAPE); - stderr.flush(); + stderr.append(StyleHelper.CLEAR_LINE_ESCAPE).flush(); } } diff --git a/smithy-cli/src/main/java/software/amazon/smithy/cli/commands/SmithyCommand.java b/smithy-cli/src/main/java/software/amazon/smithy/cli/commands/SmithyCommand.java index ae78346be4e..927586f39c9 100644 --- a/smithy-cli/src/main/java/software/amazon/smithy/cli/commands/SmithyCommand.java +++ b/smithy-cli/src/main/java/software/amazon/smithy/cli/commands/SmithyCommand.java @@ -48,6 +48,7 @@ public SmithyCommand(DependencyResolver.Factory dependencyResolverFactory) { new SelectCommand(getName(), dependencyResolverFactory), new CleanCommand(getName()), new LspCommand(getName(), dependencyResolverFactory), + new FormatCommand(getName(), dependencyResolverFactory), migrateCommand, deprecated1To2Command, new WarmupCommand(getName()) diff --git a/smithy-cli/src/main/java/software/amazon/smithy/cli/commands/StyleHelper.java b/smithy-cli/src/main/java/software/amazon/smithy/cli/commands/StyleHelper.java index 727d014ec59..c618f3a4607 100644 --- a/smithy-cli/src/main/java/software/amazon/smithy/cli/commands/StyleHelper.java +++ b/smithy-cli/src/main/java/software/amazon/smithy/cli/commands/StyleHelper.java @@ -22,6 +22,7 @@ final class StyleHelper { + static final String CLEAR_LINE_ESCAPE = "\033[2K\r"; private static final Pattern TICK_PATTERN = Pattern.compile("`(.*?)`"); private StyleHelper() {}