golang.org/x/tools/gopls@v0.15.3/doc/contributing.md (about)

     1  # Documentation for contributors
     2  
     3  This documentation augments the general documentation for contributing to the
     4  x/tools repository, described at the [repository root](../../CONTRIBUTING.md).
     5  
     6  Contributions are welcome, but since development is so active, we request that
     7  you file an issue and claim it before starting to work on something. Otherwise,
     8  it is likely that we might already be working on a fix for your issue.
     9  
    10  ## Finding issues
    11  
    12  All `gopls` issues are labeled as such (see the [`gopls` label][issue-gopls]).
    13  Issues that are suitable for contributors are additionally tagged with the
    14  [`help-wanted` label][issue-wanted].
    15  
    16  Before you begin working on an issue, please leave a comment that you are
    17  claiming it.
    18  
    19  ## Getting started
    20  
    21  Most of the `gopls` logic is in the `golang.org/x/tools/gopls/internal`
    22  directory. See [design/implementation.md] for an overview of the code organization.
    23  
    24  ## Build
    25  
    26  To build a version of `gopls` with your changes applied:
    27  
    28  ```bash
    29  cd /path/to/tools/gopls
    30  go install
    31  ```
    32  
    33  To confirm that you are testing with the correct `gopls` version, check that
    34  your `gopls` version looks like this:
    35  
    36  ```bash
    37  $ gopls version
    38  golang.org/x/tools/gopls master
    39      golang.org/x/tools/gopls@(devel)
    40  ```
    41  
    42  ## Getting help
    43  
    44  The best way to contact the gopls team directly is via the
    45  [#gopls-dev](https://app.slack.com/client/T029RQSE6/CRWSN9NCD) channel on the
    46  gophers slack. Please feel free to ask any questions about your contribution or
    47  about contributing in general.
    48  
    49  
    50  ## Error handling
    51  
    52  It is important for the user experience that, whenever practical,
    53  minor logic errors in a particular feature don't cause the server to
    54  crash.
    55  
    56  The representation of a Go program is complex. The import graph of
    57  package metadata, the syntax trees of parsed files, and their
    58  associated type information together form a huge API surface area.
    59  Even when the input is valid, there are many edge cases to consider,
    60  and this grows by an order of magnitude when you consider missing
    61  imports, parse errors, and type errors.
    62  
    63  What should you do when your logic must handle an error that you
    64  believe "can't happen"?
    65  
    66  - If it's possible to return an error, then use the `bug.Errorf`
    67    function to return an error to the user, but also record the bug in
    68    gopls' cache so that it is less likely to be ignored.
    69  
    70  - If it's safe to proceed, you can call `bug.Reportf` to record the
    71    error and continue as normal.
    72  
    73  - If there's no way to proceed, call `bug.Fatalf` to record the error
    74    and then stop the program with `log.Fatalf`. You can also use
    75    `bug.Panicf` if there's a chance that a recover handler might save
    76    the situation.
    77  
    78  - Only if you can prove locally that an error is impossible should you
    79    call `log.Fatal`. If the error may happen for some input, however
    80    unlikely, then you should use one of the approaches above. Also, if
    81    the proof of safety depends on invariants broadly distributed across
    82    the code base, then you should instead use `bug.Panicf`.
    83  
    84  Note also that panicking is preferable to `log.Fatal` because it
    85  allows VS Code's crash reporting to recognize and capture the stack.
    86  
    87  Bugs reported through `bug.Errorf` and friends are retrieved using the
    88  `gopls bug` command, which opens a GitHub Issue template and populates
    89  it with a summary of each bug and its frequency.
    90  The text of the bug is rather fastidiously printed to stdout to avoid
    91  sharing user names and error message strings (which could contain
    92  project identifiers) with GitHub.
    93  Users are invited to share it if they are willing.
    94  
    95  ## Testing
    96  
    97  The normal command you should use to run the tests after a change is:
    98  
    99  ```bash
   100  gopls$ go test -short ./...
   101  ```
   102  
   103  (The `-short` flag skips some slow-running ones. The trybot builders
   104  run the complete set, on a wide range of platforms.)
   105  
   106  Gopls tests are a mix of two kinds.
   107  
   108  - [Marker tests](../internal/test/marker) express each test scenario
   109    in a standalone text file that contains the target .go, go.mod, and
   110    go.work files, in which special annotations embedded in comments
   111    drive the test. These tests are generally easy to write and fast
   112    to iterate, but have limitations on what they can express.
   113  
   114  - [Integration tests](../internal/test/integration) are regular Go
   115    `func Test(*testing.T)` functions that make a series of calls to an
   116    API for a fake LSP-enabled client editor. The API allows you to open
   117    and edit a file, navigate to a definition, invoke other LSP
   118    operations, and assert properties about the state.
   119  
   120    Due to the asynchronous nature of the LSP, integration tests make
   121    assertions about states that the editor must achieve eventually,
   122    even when the program goes wrong quickly, it may take a while before
   123    the error is reported as a failure to achieve the desired state
   124    within several minutes. We recommend that you set
   125    `GOPLS_INTEGRATION_TEST_TIMEOUT=10s` to reduce the timeout for
   126    integration tests when debugging.
   127    
   128    When they fail, the integration tests print the log of the LSP
   129    session between client and server. Though verbose, they are very
   130    helpful for debugging once you know how to read them.
   131  
   132  Don't hesitate to [reach out](#getting-help) to the gopls team if you
   133  need help.
   134  
   135  ### CI
   136  
   137  When you mail your CL and you or a fellow contributor assigns the
   138  `Run-TryBot=1` label in Gerrit, the
   139  [TryBots](https://golang.org/doc/contribute.html#trybots) will run tests in
   140  both the `golang.org/x/tools` and `golang.org/x/tools/gopls` modules, as
   141  described above.
   142  
   143  Furthermore, an additional "gopls-CI" pass will be run by _Kokoro_, which is a
   144  Jenkins-like Google infrastructure for running Dockerized tests. This allows us
   145  to run gopls tests in various environments that would be difficult to add to
   146  the TryBots. Notably, Kokoro runs tests on
   147  [older Go versions](../README.md#supported-go-versions) that are no longer supported
   148  by the TryBots. Per that that policy, support for these older Go versions is
   149  best-effort, and test failures may be skipped rather than fixed.
   150  
   151  Kokoro runs are triggered by the `Run-TryBot=1` label, just like TryBots, but
   152  unlike TryBots they do not automatically re-run if the "gopls-CI" result is
   153  removed in Gerrit. To force a re-run of the Kokoro CI on a CL containing the
   154  `Run-TryBot=1` label, you can reply in Gerrit with the comment "kokoro rerun".
   155  
   156  ## Debugging
   157  
   158  The easiest way to debug your change is to run a single `gopls` test with a
   159  debugger.
   160  
   161  See also [Troubleshooting](troubleshooting.md#troubleshooting).
   162  
   163  <!--TODO(rstambler): Add more details about the debug server and viewing
   164  telemetry.-->
   165  
   166  [issue-gopls]: https://github.com/golang/go/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+label%3Agopls "gopls issues"
   167  [issue-wanted]: https://github.com/golang/go/issues?utf8=✓&q=is%3Aissue+is%3Aopen+label%3Agopls+label%3A"help+wanted" "help wanted"