diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..0c8b092c4 --- /dev/null +++ b/.github/CODE_OF_CONDUCT.md @@ -0,0 +1,5 @@ +# Code of Conduct + +HashiCorp Community Guidelines apply to you when interacting with the community here on GitHub and contributing code. + +Please read the full text at https://www.hashicorp.com/community-guidelines diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 000000000..b2f14f05a --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,212 @@ +# Contributing to Terraform Language Server + +## Reporting Feedback + +Terraform Language Server is an open source project and we appreciate +contributions of various kinds, including bug reports and fixes, +enhancement proposals, documentation updates, and user experience feedback. + +To record a bug report, enhancement proposal, or give any other product +feedback, please [open a GitHub issue](https://github.com/hashicorp/terraform-ls/issues/new/choose) +using the most appropriate issue template. Please do fill in all of the +information the issue templates request, because we've seen from experience that +this will maximize the chance that we'll be able to act on your feedback. + +**All communication on GitHub, the community forum, and other HashiCorp-provided +communication channels is subject to +[the HashiCorp community guidelines](https://www.hashicorp.com/community-guidelines).** + +## Scope + +This repository contains the source code only for Terraform Language Server, +which in turn relies on other projects that have their own repositories. + +[Terraform CLI/core has its own repository.](https://github.com/hashicorp/terraform) + +The HashiCorp-maintained Terraform providers are open source but are **not** +in this repository; instead, they are each in their own repository in +[the `terraform-providers` organization](https://github.com/terraform-providers) +on GitHub. + +This repository also does **not** include the source code for some other parts of +the Terraform product including Terraform Cloud, Terraform Enterprise, and the +Terraform Registry. Those components are not open source, though if you have +feedback about them (including bug reports) please do feel free to +[open a GitHub issue in the core repository](https://github.com/hashicorp/terraform/issues/new/choose). + +## Development + +If you wish to work on the source code, you'll first need to install + the [Go](https://golang.org/) compiler and the version control system +[Git](https://git-scm.com/). + +Refer to the file [`.go-version`](.go-version) to see which version of Go +the Language Server is currently built with. Other versions will often work, +but if you run into any build or testing problems please try with the specific +Go version indicated. You can optionally simplify the installation of multiple +specific versions of Go on your system by installing +[`goenv`](https://github.com/syndbg/goenv), which reads `.go-version` and +automatically selects the correct Go version. + +Use Git to clone this repository into a location of your choice. Dependencies +are tracked via [Go Modules](https://blog.golang.org/using-go-modules), +and so you should _not_ clone it inside your `GOPATH`. + +Switch into the root directory of the cloned repository and build +the Language Server using the Go toolchain in the standard way: + +``` +cd terraform-ls +go install . +``` + +Once the compilation process succeeds, you can find a `terraform-ls` executable in +the Go executable directory. If you haven't overridden it with the `GOBIN` +environment variable, the executable directory is the `bin` directory inside +the directory returned by the following command: + +``` +go env GOPATH +``` + +If you are planning to make changes to the source code, you should run the +unit test suite before you start to make sure everything is initially passing: + +``` +go test ./... +``` + +As you make your changes, you can re-run the above command to ensure that the +tests are _still_ passing. If you are working only on a specific Go package, +you can speed up your testing cycle by testing only that single package, or +packages under a particular package prefix: + +``` +go test ./internal/terraform/exec/... +go test ./langserver +``` + +## External Dependencies + +Terraform uses [Go Modules]((https://blog.golang.org/using-go-modules)) +for dependency management, but currently uses "vendoring" to include +copies of all of the external library dependencies in the repository +to allow builds to complete even if third-party dependency sources +are unavailable. + +If you need to add a new dependency to Terraform or update the selected version +for an existing one, use `go get` from the root of the Terraform repository +as follows: + +``` +go get github.com/hashicorp/hcl/v2@2.0.0 +``` + +This command will download the requested version (2.0.0 in the above example) +and record that version selection in the `go.mod` file. It will also record +checksums for the module in the `go.sum`. + +To complete the dependency change, clean up any redundancy in the module +metadata files and resynchronize the `vendor` directory with the new package +selections by running the following commands: + +``` +go mod tidy +go mod vendor +``` + +To ensure that the vendoring has worked correctly, be sure to run the unit +test suite at least once in _vendoring_ mode, where Go will use the vendored +dependencies to build the test programs: + +``` +go test -mod=vendor ./... +``` + +Because dependency changes affect a shared, top-level file, they are more likely +than some other change types to become conflicted with other proposed changes +during the code review process. For that reason, and to make dependency changes +more visible in the change history, we prefer to record dependency changes as +separate commits that include only the results of the above commands and the +minimal set of changes to the Language Server's own code for compatibility +with the new version: + +``` +git add go.mod go.sum vendor +git commit -m "vendor: go get github.com/hashicorp/hcl/v2@2.0.0" +``` + +You can then make use of the new or updated dependency in new code added in +subsequent commits. + +### Licensing Policy + +Our dependency licensing policy excludes proprietary licenses and "copyleft"-style +licenses. We accept the common Mozilla Public License v2, MIT License, +and BSD licenses. We will consider other open source licenses +in similar spirit to those three, but if you plan to include such a dependency +in a contribution we'd recommend opening a GitHub issue first to discuss what +you intend to implement and what dependencies it will require so that the +maintainer team can review the relevant licenses to for whether +they meet our licensing needs. + +## Debugging + +[PacketSender](https://packetsender.com) enables you to open a TCP socket with a server, when launched as such. +Approximate steps of debugging follow. + + - Install PacketSender (e.g. on MacOS via `brew cask install packet-sender`) + - Launch LS in TCP mode: `terraform-ls serve -port=8080` + - Send any requests via PacketSender + - Set `Address` to `127.0.0.1` + - Set `Port` to `8080` + - Tick `Persistent TCP` + - Hit the `Send` button (which opens the TCP connection) + - Paste or type request in LSP format (see below) & hit `Send` + +Examples of formatted requests follow. + +``` +Content-Length: 164\n\n{"jsonrpc":"2.0","params":{"textDocument":{"uri":"file:///var/path/to/file/main.tf"},"position":{"line":1,"character":0}},"method":"textDocument/completion","id":2} +``` +``` +Content-Length: 72\n\n{"jsonrpc":"2.0","params":{"id":2},"method":"$/cancelRequest","id":null} +``` +``` +Content-Length: 47\n\n{"jsonrpc":"2.0","method":"shutdown","id":null} +``` + +Keep in mind that each TCP session receives an isolated context, +so you cannot cancel requests you didn't start yourself + +## Proposing a Change + +If you'd like to contribute a code change, we'd love to review a GitHub pull request. + +In order to be respectful of the time of community contributors, we prefer to +discuss potential changes in GitHub issues prior to implementation. That will +allow us to give design feedback up front and set expectations about the scope +of the change, and, for larger changes, how best to approach the work such that +the maintainer team can review it and merge it along with other concurrent work. + +If the bug you wish to fix or enhancement you wish to implement isn't already +covered by a GitHub issue that contains feedback from the maintainer team, +please do start a discussion (either in +[a new GitHub issue](https://github.com/hashicorp/terraform-ls/issues/new/choose) +or an existing one, as appropriate) before you invest significant development +time. If you mention your intent to implement the change described in your +issue, the maintainer team can prioritize including implementation-related +feedback in the subsequent discussion. + +Most changes will involve updates to the test suite, and changes to the +documentation. The maintainer team can advise on different testing strategies +for specific scenarios, and may ask you to revise the specific phrasing of +your proposed documentation prose to match better with the standard "voice" of +Terraform's documentation. + +This repository is primarily maintained by a small team at HashiCorp along with +their other responsibilities, so unfortunately we cannot always respond +promptly to pull requests, particularly if they do not relate to an existing +GitHub issue where the maintainer team has already participated. We _are_ +grateful for all contributions however, and will give feedback on pull requests +as soon as we're able to. diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 000000000..80a1422b2 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,72 @@ +--- +name: Bug report +about: Let us know about an unexpected error, a crash, or an incorrect behavior. + +--- + +### Server Version + +``` + +``` + +### Terraform Version + +``` + +``` + +### Client Version + +``` + +``` + +### Terraform Configuration Files + + +```hcl + +``` + +### Log Output + + +### Expected Behavior + + +### Actual Behavior + + +### Steps to Reproduce + diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 000000000..7c6b422f4 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,14 @@ +blank_issues_enabled: false +contact_links: + - name: Provider-related Feedback and Questions + url: https://github.com/terraform-providers + about: Each provider (e.g. AWS, Azure, GCP, Oracle, K8S, etc.) has its own repository, any provider related issues or questions should be directed to appropriate provider repository. + - name: Provider Development Feedback and Questions + url: https://github.com/hashicorp/terraform-plugin-sdk/issues/new/choose + about: Plugin SDK has its own repository, any SDK and provider development related issues or questions should be directed there. + - name: Terraform Language or Workflow Feedback and Questions + url: https://github.com/hashicorp/terraform/issues/new/choose + about: Terraform Core has its own repository, any language (HCL) or workflow related issues or questions should be directed there. + - name: Terraform Language or Workflow Questions + url: https://discuss.hashicorp.com/c/terraform-core + about: Please ask and answer language or workflow related questions through the Terraform Core Community Forum. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 000000000..f4360894e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,55 @@ +--- +name: Feature request +about: Suggest a new feature or other enhancement. +labels: enhancement +--- + +### Current Version + +``` + +``` + +### Use-cases + + +### Attempted Solutions + + +### Proposal + + +### Related LSP methods + + +### References + diff --git a/.github/SECURITY.md b/.github/SECURITY.md new file mode 100644 index 000000000..6cffe8c42 --- /dev/null +++ b/.github/SECURITY.md @@ -0,0 +1,4 @@ +# Vulnerability Reporting + +Please disclose security vulnerabilities responsibly by following the procedure +described at https://www.hashicorp.com/security#vulnerability-reporting diff --git a/.github/SUPPORT.md b/.github/SUPPORT.md new file mode 100644 index 000000000..23b0deaf4 --- /dev/null +++ b/.github/SUPPORT.md @@ -0,0 +1,4 @@ +# Support + +If you have questions about Terraform Language Server usage, please feel free to create a topic +on [the official community forum](https://discuss.hashicorp.com/c/terraform-core). diff --git a/README.md b/README.md index 256cdd3a8..eb839860b 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,26 @@ # Terraform Language Server -Experimental version of Terraform Language Server. +Experimental version of [Terraform](https://www.terraform.io) Language Server. -Not all LSP or language features are available at the time of writing as this is an active project with the aim of delivering smaller, incremental updates over time. +## What is LSP -## What is Terraform? +Read more about the Language Server Protocol at https://microsoft.github.io/language-server-protocol/ -[Terraform](https://www.terraform.io) enables you to safely and predictably create, change, and improve infrastructure. It is an open source tool that codifies APIs into declarative configuration files that can be shared amongst team members, treated as code, edited, reviewed, and versioned. +## Current Status -## What is Language Server? +Not all language features (from LSP's or any other perspective) are available +at the time of writing, but this is an active project with the aim of delivering +smaller, incremental updates over time. -A server implementing the [Language Server Protocol](https://microsoft.github.io/language-server-protocol/) (LSP), which in turn defines the protocol used between an editor or IDE and a language server that provides language features like auto complete, go to definition, find all references etc. +We encourage you to [browse existing issues](https://github.com/hashicorp/terraform-ls/issues) +and/or [open new issue](https://github.com/hashicorp/terraform-ls/issues/new/choose) +if you experience a bug or have an idea for a feature. ## Disclaimer This is not an officially supported HashiCorp product. -## How to try it out +## Installation ``` go install . @@ -27,106 +31,16 @@ This should produce a binary called `terraform-ls` in `$GOBIN/terraform-ls`. Putting `$GOBIN` in your `$PATH` may save you from having to specify absolute path to the binary. -### Visual Studio Code +## Usage -Try https://github.com/aeschright/tf-vscode-demo/pull/1 - instructions are in that PR. +The most reasonable way you will interact with the language server +is through a client represented by an IDE, or a plugin of an IDE. -### Sublime Text 2 - - - Install the [LSP package](https://github.com/sublimelsp/LSP#installation) - - Add the following snippet to the LSP settings' `clients`: - -```json -"terraform": { - "command": ["terraform-ls", "serve"], - "enabled": true, - "languageId": "terraform", - "scopes": ["source.terraform"], - "syntaxes": ["Packages/Terraform/Terraform.sublime-syntax"] -} -``` - -## Troubleshooting - -The language server produces detailed logs which are send to stderr by default. -Most IDEs provide a way of inspecting these logs when server is launched in the standard -stdin/stdout mode. - -Logs can also be redirected into file using flags of the `serve` command, e.g. - -```sh -$ terraform-ls serve -log-file=/tmp/terraform-ls-{{pid}}.log -tf-log-file=/tmp/tf-exec-{{lsPid}}-{{args}}.log -``` - -It is recommended to inspect these logs when reporting bugs. - -### Log Rotation - -Keep in mind that the language server itself does not have any log rotation facility, -but the destination path will be truncated before being logged into. - -Static paths may produce large files over the lifetime of the server and -templated paths (as described below) may produce many log files over time. - -### Log Path Templating - -Log paths support template syntax. This allows sane separation of logs while accounting for: - - - multiple server instances - - multiple clients - - multiple Terraform executions which may happen in parallel - -**`-log-file`** supports the following functions: - - - `timestamp` - current timestamp (formatted as [`Time.Unix()`](https://golang.org/pkg/time/#Time.Unix), i.e. the number of seconds elapsed since January 1, 1970 UTC) - - `pid` - process ID of the language server - - `ppid` - parent process ID (typically editor's or editor plugin's PID) - - **`-tf-log-file`** supports the following functions: - - - `timestamp` - current timestamp (formatted as [`Time.Unix()`](https://golang.org/pkg/time/#Time.Unix), i.e. the number of seconds elapsed since January 1, 1970 UTC) - - `lsPid` - process ID of the language server - - `lsPpid` - parent process ID of the language server (typically editor's or editor plugin's PID) - - `args` - all arguments passed to `terraform` turned into a safe `-` separated string - -The path is interpreted as [Go template](https://golang.org/pkg/text/template/), e.g. `/tmp/terraform-ls-{{timestamp}}.log`. - -## Contributing/Development - -### Troubleshooting - -[PacketSender](https://packetsender.com) enables you to open a TCP socket with a server, when launched as such. -Approximate steps of debugging follow. - - - Install PacketSender (e.g. on MacOS via `brew cask install packet-sender`) - - Launch LS in TCP mode: `terraform-ls serve -port=8080` - - Send any requests via PacketSender - - Set `Address` to `127.0.0.1` - - Set `Port` to `8080` - - Tick `Persistent TCP` - - Hit the `Send` button (which opens the TCP connection) - - Paste or type request in LSP format (see below) & hit `Send` - -Examples of formatted requests follow. - -``` -Content-Length: 164\n\n{"jsonrpc":"2.0","params":{"textDocument":{"uri":"file:///var/path/to/file/main.tf"},"position":{"line":1,"character":0}},"method":"textDocument/completion","id":2} -``` -``` -Content-Length: 72\n\n{"jsonrpc":"2.0","params":{"id":2},"method":"$/cancelRequest","id":null} -``` -``` -Content-Length: 47\n\n{"jsonrpc":"2.0","method":"shutdown","id":null} -``` - -### Notes - - - Keep in mind that each TCP session receives an isolated context, - so you cannot cancel requests you didn't start yourself +Please follow the [relevant guide for your IDE](./docs/USAGE.md). ## Credits -The implementation was inspired by: - - - [`juliosueiras/terraform-lsp`](https://github.com/juliosueiras/terraform-lsp) - - [Martin Atkins](https://github.com/apparentlymart) (particularly the virtual filesystem) +- [Martin Atkins](https://github.com/apparentlymart) - particularly the virtual filesystem +- [Zhe Cheng](https://github.com/njuCZ) - research, design, prototyping assistance +- [Julio Sueiras](https://github.com/juliosueiras) - particularly his [language server implementation](https://github.com/juliosueiras/terraform-lsp) + diff --git a/docs/TROUBLESHOOTING.md b/docs/TROUBLESHOOTING.md new file mode 100644 index 000000000..23cf667df --- /dev/null +++ b/docs/TROUBLESHOOTING.md @@ -0,0 +1,46 @@ +## Troubleshooting + +The language server produces detailed logs which are send to stderr by default. +Most IDEs provide a way of inspecting these logs when server is launched in the standard +stdin/stdout mode. + +Logs can also be redirected into file using flags of the `serve` command, e.g. + +```sh +$ terraform-ls serve \ + -log-file=/tmp/terraform-ls-{{pid}}.log \ + -tf-log-file=/tmp/tf-exec-{{lsPid}}-{{args}}.log +``` + +It is recommended to inspect these logs when reporting bugs. + +### Log Rotation + +Keep in mind that the language server itself does not have any log rotation facility, +but the destination path will be truncated before being logged into. + +Static paths may produce large files over the lifetime of the server and +templated paths (as described below) may produce many log files over time. + +### Log Path Templating + +Log paths support template syntax. This allows sane separation of logs while accounting for: + + - multiple server instances + - multiple clients + - multiple Terraform executions which may happen in parallel + +**`-log-file`** supports the following functions: + + - `timestamp` - current timestamp (formatted as [`Time.Unix()`](https://golang.org/pkg/time/#Time.Unix), i.e. the number of seconds elapsed since January 1, 1970 UTC) + - `pid` - process ID of the language server + - `ppid` - parent process ID (typically editor's or editor plugin's PID) + + **`-tf-log-file`** supports the following functions: + + - `timestamp` - current timestamp (formatted as [`Time.Unix()`](https://golang.org/pkg/time/#Time.Unix), i.e. the number of seconds elapsed since January 1, 1970 UTC) + - `lsPid` - process ID of the language server + - `lsPpid` - parent process ID of the language server (typically editor's or editor plugin's PID) + - `args` - all arguments passed to `terraform` turned into a safe `-` separated string + +The path is interpreted as [Go template](https://golang.org/pkg/text/template/), e.g. `/tmp/terraform-ls-{{timestamp}}.log`. diff --git a/docs/USAGE.md b/docs/USAGE.md new file mode 100644 index 000000000..3c8033fd4 --- /dev/null +++ b/docs/USAGE.md @@ -0,0 +1,23 @@ +# Usage of Terraform Language Server + +This guide assumes you have installed the server by following instructions +in the [README.md](../README.md) if that is applicable to your client +(i.e. if the client doesn't download the server itself). + +Instructions for popular IDEs are below and pull requests +for updates or addition of more IDEs are welcomed. + +## Sublime Text 2 + + - Install the [LSP package](https://github.com/sublimelsp/LSP#installation) + - Add the following snippet to the LSP settings' `clients`: + +```json +"terraform": { + "command": ["terraform-ls", "serve"], + "enabled": true, + "languageId": "terraform", + "scopes": ["source.terraform"], + "syntaxes": ["Packages/Terraform/Terraform.sublime-syntax"] +} +```