lang.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /* Copyright 2018 The Bazel Authors. All rights reserved.
  2. Licensed under the Apache License, Version 2.0 (the "License");
  3. you may not use this file except in compliance with the License.
  4. You may obtain a copy of the License at
  5. http://www.apache.org/licenses/LICENSE-2.0
  6. Unless required by applicable law or agreed to in writing, software
  7. distributed under the License is distributed on an "AS IS" BASIS,
  8. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9. See the License for the specific language governing permissions and
  10. limitations under the License.
  11. */
  12. // Package language provides an interface for language extensions in Gazelle.
  13. // Support for a new language can be added by defining a package with a
  14. // function named "New" that returns a value assignable to this interface.
  15. //
  16. // TODO(jayconrod): document how to incorporate languages into a gazelle
  17. // binary that can be run by Bazel.
  18. package language
  19. import (
  20. "github.com/bazelbuild/bazel-gazelle/config"
  21. "github.com/bazelbuild/bazel-gazelle/resolve"
  22. "github.com/bazelbuild/bazel-gazelle/rule"
  23. )
  24. // Language describes an extension for Gazelle that provides support for
  25. // a set of Bazel rules.
  26. //
  27. // Languages are used primarily by the fix and update commands. The order
  28. // in which languages are used matters, since languages may depend on
  29. // one another. For example, go depends on proto, since go_proto_libraries
  30. // are generated from metadata stored in proto_libraries.
  31. //
  32. // A single instance of Language is created for each fix / update run. Some
  33. // state may be stored in this instance, but stateless behavior is encouraged,
  34. // especially since some operations may be concurrent in the future.
  35. //
  36. // Tasks languages are used for
  37. //
  38. // * Configuration (embedded interface config.Configurer). Languages may
  39. // define command line flags and alter the configuration in a directory
  40. // based on directives in build files.
  41. //
  42. // * Fixing deprecated usage of rules in build files.
  43. //
  44. // * Generating rules from source files in a directory.
  45. //
  46. // * Resolving library imports (embedded interface resolve.Resolver). For
  47. // example, import strings like "github.com/foo/bar" in Go can be resolved
  48. // into Bazel labels like "@com_github_foo_bar//:go_default_library".
  49. //
  50. // Tasks languages support
  51. //
  52. // * Generating load statements: languages list files and symbols that may
  53. // be loaded.
  54. //
  55. // * Merging generated rules into existing rules: languages provide metadata
  56. // that helps with rule matching, merging, and deletion.
  57. type Language interface {
  58. // TODO(jayconrod): is embedding Configurer strictly necessary?
  59. config.Configurer
  60. resolve.Resolver
  61. // Kinds returns a map of maps rule names (kinds) and information on how to
  62. // match and merge attributes that may be found in rules of those kinds. All
  63. // kinds of rules generated for this language may be found here.
  64. Kinds() map[string]rule.KindInfo
  65. // Loads returns .bzl files and symbols they define. Every rule generated by
  66. // GenerateRules, now or in the past, should be loadable from one of these
  67. // files.
  68. Loads() []rule.LoadInfo
  69. // GenerateRules extracts build metadata from source files in a directory.
  70. // GenerateRules is called in each directory where an update is requested
  71. // in depth-first post-order.
  72. //
  73. // args contains the arguments for GenerateRules. This is passed as a
  74. // struct to avoid breaking implementations in the future when new
  75. // fields are added.
  76. //
  77. // A GenerateResult struct is returned. Optional fields may be added to this
  78. // type in the future.
  79. //
  80. // Any non-fatal errors this function encounters should be logged using
  81. // log.Print.
  82. GenerateRules(args GenerateArgs) GenerateResult
  83. // Fix repairs deprecated usage of language-specific rules in f. This is
  84. // called before the file is indexed. Unless c.ShouldFix is true, fixes
  85. // that delete or rename rules should not be performed.
  86. Fix(c *config.Config, f *rule.File)
  87. }
  88. // GenerateArgs contains arguments for language.GenerateRules. Arguments are
  89. // passed in a struct value so that new fields may be added in the future
  90. // without breaking existing implementations.
  91. type GenerateArgs struct {
  92. // Config is the configuration for the directory where rules are being
  93. // generated.
  94. Config *config.Config
  95. // Dir is the canonical absolute path to the directory.
  96. Dir string
  97. // Rel is the slash-separated path to the directory, relative to the
  98. // repository root ("" for the root directory itself). This may be used
  99. // as the package name in labels.
  100. Rel string
  101. // File is the build file for the directory. File is nil if there is
  102. // no existing build file.
  103. File *rule.File
  104. // Subdirs is a list of subdirectories in the directory, including
  105. // symbolic links to directories that Gazelle will follow.
  106. // RegularFiles is a list of regular files including other symbolic
  107. // links.
  108. // GeneratedFiles is a list of generated files in the directory
  109. // (usually these are mentioned as "out" or "outs" attributes in rules).
  110. Subdirs, RegularFiles, GenFiles []string
  111. // OtherEmpty is a list of empty rules generated by other languages.
  112. // OtherGen is a list of generated rules generated by other languages.
  113. OtherEmpty, OtherGen []*rule.Rule
  114. }
  115. // GenerateResult contains return values for language.GenerateRules.
  116. // Results are returned through a struct value so that new (optional)
  117. // fields may be added without breaking existing implementations.
  118. type GenerateResult struct {
  119. // Gen is a list of rules generated from files found in the directory
  120. // GenerateRules was asked to process. These will be merged with existing
  121. // rules or added to the build file.
  122. Gen []*rule.Rule
  123. // Empty is a list of rules that cannot be built with the files found in the
  124. // directory GenerateRules was asked to process. These will be merged with
  125. // existing rules. If ther merged rules are empty, they will be deleted.
  126. Empty []*rule.Rule
  127. // Imports contains information about the imported libraries for each
  128. // rule in Gen. Gen and Imports must have the same length, since they
  129. // correspond. These values are passed to Resolve after merge. The type
  130. // is opaque since different languages may use different representations.
  131. Imports []interface{}
  132. }