yql_linter.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. #include <yql/essentials/public/fastcheck/linter.h>
  2. #include <yql/essentials/utils/tty.h>
  3. #include <library/cpp/getopt/last_getopt.h>
  4. #include <google/protobuf/arena.h>
  5. #include <library/cpp/colorizer/output.h>
  6. #include <util/generic/serialized_enum.h>
  7. #include <util/stream/file.h>
  8. int Run(int argc, char* argv[]) {
  9. NLastGetopt::TOpts opts = NLastGetopt::TOpts::Default();
  10. TString inFileName;
  11. TString queryString;
  12. TString checks;
  13. THashMap<TString, TString> clusterMapping;
  14. TString modeStr = "Default";
  15. TString syntaxStr = "YQL";
  16. TString clusterModeStr = "Many";
  17. TString clusterSystem;
  18. opts.AddLongOption('i', "input", "input file").RequiredArgument("input").StoreResult(&inFileName);
  19. opts.AddLongOption('v', "verbose", "show lint issues").NoArgument();
  20. opts.AddLongOption("list-checks", "list all enabled checks and exit").NoArgument();
  21. opts.AddLongOption("checks", "comma-separated list of globs with optional '-' prefix").StoreResult(&checks);
  22. opts.AddLongOption('C', "cluster", "cluster to service mapping").RequiredArgument("name@service")
  23. .KVHandler([&](TString cluster, TString provider) {
  24. if (cluster.empty() || provider.empty()) {
  25. throw yexception() << "Incorrect service mapping, expected form cluster@provider, e.g. plato@yt";
  26. }
  27. clusterMapping[cluster] = provider;
  28. }, '@');
  29. opts.AddLongOption('m', "mode", "query mode, allowed values: " + GetEnumAllNames<NYql::NFastCheck::EMode>()).StoreResult(&modeStr);
  30. opts.AddLongOption('s', "syntax", "query syntax, allowed values: " + GetEnumAllNames<NYql::NFastCheck::ESyntax>()).StoreResult(&syntaxStr);
  31. opts.AddLongOption("cluster-mode", "cluster mode, allowed values: " + GetEnumAllNames<NYql::NFastCheck::EClusterMode>()).StoreResult(&clusterModeStr);
  32. opts.AddLongOption("cluster-system", "cluster system").StoreResult(&clusterSystem);
  33. opts.AddLongOption("ansi-lexer", "use ansi lexer").NoArgument();
  34. opts.AddLongOption("no-colors", "disable colors for output").NoArgument();
  35. opts.SetFreeArgsNum(0);
  36. opts.AddHelpOption();
  37. NLastGetopt::TOptsParseResult res(&opts, argc, argv);
  38. const bool colorize = !res.Has("no-colors") && IsTty(NYql::EStdStream::Out);
  39. NYql::NFastCheck::TChecksRequest checkReq;
  40. if (res.Has("checks")) {
  41. checkReq.Filters = NYql::NFastCheck::ParseChecks(checks);
  42. }
  43. if (res.Has("list-checks")) {
  44. for (const auto& c : NYql::NFastCheck::ListChecks(checkReq.Filters)) {
  45. if (colorize) {
  46. Cout << NColorizer::LightCyan();
  47. }
  48. Cout << c;
  49. if (colorize) {
  50. Cout << NColorizer::Old();
  51. }
  52. Cout << '\n';
  53. }
  54. return 0;
  55. }
  56. THolder<TUnbufferedFileInput> inFile;
  57. if (!inFileName.empty()) {
  58. inFile.Reset(new TUnbufferedFileInput(inFileName));
  59. }
  60. IInputStream& in = inFile ? *inFile.Get() : Cin;
  61. queryString = in.ReadAll();
  62. int errors = 0;
  63. TString queryFile("query");
  64. checkReq.IsAnsiLexer = res.Has("ansi-lexer");
  65. checkReq.Program = queryString;
  66. checkReq.Syntax = NYql::NFastCheck::ESyntax::YQL;
  67. checkReq.ClusterMapping = clusterMapping;
  68. checkReq.Mode = FromString<NYql::NFastCheck::EMode>(modeStr);
  69. checkReq.Syntax = FromString<NYql::NFastCheck::ESyntax>(syntaxStr);
  70. checkReq.ClusterMode = FromString<NYql::NFastCheck::EClusterMode>(clusterModeStr);
  71. checkReq.ClusterSystem = clusterSystem;
  72. auto checkResp = NYql::NFastCheck::RunChecks(checkReq);
  73. for (const auto& c : checkResp.Checks) {
  74. if (!c.Success) {
  75. errors = 1;
  76. }
  77. if (colorize) {
  78. Cout << NColorizer::LightCyan();
  79. }
  80. Cout << c.CheckName << " ";
  81. if (colorize) {
  82. Cout << (c.Success ? NColorizer::Green() : NColorizer::LightRed());
  83. }
  84. Cout << (c.Success ? "PASSED" : "FAIL");
  85. if (colorize) {
  86. Cout << NColorizer::Old();
  87. }
  88. Cout << "\n";
  89. if (res.Has("verbose")) {
  90. c.Issues.PrintWithProgramTo(Cout, inFileName, queryString, colorize);
  91. }
  92. }
  93. return errors;
  94. }
  95. int main(int argc, char* argv[]) {
  96. try {
  97. return Run(argc, argv);
  98. } catch (const yexception& e) {
  99. Cerr << "Caught exception:" << e.what() << Endl;
  100. return 1;
  101. } catch (...) {
  102. Cerr << CurrentExceptionMessage() << Endl;
  103. return 1;
  104. }
  105. return 0;
  106. }