All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github._1c_syntax.bsl.languageserver.BSLLSPLauncher Maven / Gradle / Ivy

Go to download

Language Server Protocol implementation for 1C (BSL) - 1C:Enterprise 8 and OneScript languages.

There is a newer version: 0.24.0-rc.1
Show newest version
/*
 * This file is a part of BSL Language Server.
 *
 * Copyright (c) 2018-2024
 * Alexey Sosnoviy , Nikita Fedkin  and contributors
 *
 * SPDX-License-Identifier: LGPL-3.0-or-later
 *
 * BSL Language Server is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3.0 of the License, or (at your option) any later version.
 *
 * BSL Language Server 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with BSL Language Server.
 */
package com.github._1c_syntax.bsl.languageserver;

import com.github._1c_syntax.bsl.languageserver.cli.AnalyzeCommand;
import com.github._1c_syntax.bsl.languageserver.cli.FormatCommand;
import com.github._1c_syntax.bsl.languageserver.cli.LanguageServerStartCommand;
import com.github._1c_syntax.bsl.languageserver.cli.VersionCommand;
import com.github._1c_syntax.bsl.languageserver.cli.WebsocketCommand;
import com.github._1c_syntax.utils.CaseInsensitivePattern;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.ExitCodeGenerator;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.stereotype.Component;
import picocli.CommandLine;
import picocli.CommandLine.Option;
import picocli.CommandLine.Unmatched;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static picocli.CommandLine.Command;

@Command(
  name = "bsl-language-server",
  subcommands = {
    AnalyzeCommand.class,
    FormatCommand.class,
    VersionCommand.class,
    LanguageServerStartCommand.class,
    WebsocketCommand.class
  },
  usageHelpAutoWidth = true,
  synopsisSubcommandLabel = "[COMMAND [ARGS]]",
  footer = "@|green Copyright(c) 2018-2022|@",
  header = "@|green BSL language server|@")
@SpringBootApplication(scanBasePackageClasses = BSLLSPLauncher.class)
@Component
@ConditionalOnProperty(
  prefix = "app.command.line.runner",
  value = "enabled",
  havingValue = "true",
  matchIfMissing = true)
@RequiredArgsConstructor
public class BSLLSPLauncher implements Callable, ExitCodeGenerator {

  private static final String DEFAULT_COMMAND = "lsp";

  @Option(
    names = {"-h", "--help"},
    usageHelp = true,
    description = "Show this help message and exit")
  private boolean usageHelpRequested;

  @Option(
    names = {"-c", "--configuration"},
    description = "Path to language server configuration file",
    paramLabel = "",
    defaultValue = "")
  private String configurationOption;

  @Unmatched
  private List unmatched;

  private final Set allowedAdditionalArgs = Set.of(
    CaseInsensitivePattern.compile("--spring\\."),
    CaseInsensitivePattern.compile("--app\\."),
    CaseInsensitivePattern.compile("--logging\\."),
    CaseInsensitivePattern.compile("--debug")
  );

  private final CommandLine.IFactory picocliFactory;

  private int exitCode;

  public static void main(String[] args) {
    var applicationContext = new SpringApplicationBuilder(BSLLSPLauncher.class)
      .web(getWebApplicationType(args))
      .run(args);

    var launcher = applicationContext.getBean(BSLLSPLauncher.class);
    launcher.run(args);

    if (launcher.getExitCode() >= 0) {
      System.exit(
        SpringApplication.exit(applicationContext)
      );
    }
  }

  public void run(String... args) {
    var cmd = new CommandLine(this, picocliFactory);

    // проверка использования дефолтной команды
    // если строка параметров пуста, то это точно вызов команды по умолчанию
    if (args.length == 0) {
      args = addDefaultCommand(args);
    } else {
      var parseResult = cmd.parseArgs(args);
      var unmatchedArgs = parseResult.unmatched().stream()
        .filter(s -> allowedAdditionalArgs.stream().noneMatch(pattern -> pattern.matcher(s).matches()))
        .collect(Collectors.toList());

      if (!unmatchedArgs.isEmpty()) {
        unmatchedArgs.forEach(s -> cmd.getErr().println("Unknown option: '" + s + "'"));
        cmd.usage(cmd.getOut());
        exitCode = cmd.getCommandSpec().exitCodeOnInvalidInput();
        return;
      }

      // если переданы параметры без команды и это не справка
      // то считаем, что параметры для команды по умолчанию
      if (!parseResult.hasSubcommand() && !parseResult.isUsageHelpRequested()) {
        args = addDefaultCommand(args);
      }
    }

    exitCode = cmd.execute(args);

  }

  private static String[] addDefaultCommand(String[] args) {
    List tmpList = new ArrayList<>(Arrays.asList(args));
    tmpList.add(0, DEFAULT_COMMAND);
    args = tmpList.toArray(new String[0]);
    return args;
  }

  @Override
  public int getExitCode() {
    return exitCode;
  }

  public Integer call() {
    // заглушка, командой как таковой не пользуемся
    return 0;
  }

  private static WebApplicationType getWebApplicationType(String[] args) {
    WebApplicationType webApplicationType;
    var argsList = Arrays.asList(args);
    if (argsList.contains("-w") || argsList.contains("websocket")) {
      webApplicationType = WebApplicationType.SERVLET;
    } else {
      webApplicationType = WebApplicationType.NONE;
    }
    return webApplicationType;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy