diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..b7114e97 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,619 @@ +# Contributing to Konveyor Analyzer LSP + +Welcome! This guide will help you contribute to the Konveyor Analyzer LSP project. + +## Table of Contents + +- [Development Environment Setup](#development-environment-setup) +- [Building the Project](#building-the-project) +- [Testing Your Changes](#testing-your-changes) +- [Container-Based Development](#container-based-development) +- [Adding New Rules](#adding-new-rules) +- [Adding New Language Support](#adding-new-language-support) +- [Common Issues and Solutions](#common-issues-and-solutions) +- [Pull Request Process](#pull-request-process) + +## Development Environment Setup + +### Prerequisites + +- **Go 1.21+** - For building the analyzer and Go provider +- **Java 17+** - For Java provider (JDTLS) +- **Node.js 18+** - For Node.js/TypeScript provider +- **Python 3.9+** - For Python provider +- **Podman or Docker** - For container-based testing +- **Make** - For build automation + +### Clone the Repository + +```bash +git clone https://github.com/konveyor/analyzer-lsp.git +cd analyzer-lsp +``` + +### Install Dependencies + +The project uses multiple language servers. Install them based on which providers you're working with: + +**TypeScript/JavaScript Provider:** +```bash +npm install -g typescript typescript-language-server +``` + +**Python Provider:** +```bash +python3 -m pip install 'python-lsp-server>=1.8.2' +``` + +**Go Provider:** +```bash +go install golang.org/x/tools/gopls@latest +``` + +**Java Provider:** +Java provider uses Eclipse JDTLS which is bundled in the container image. + +## Building the Project + +### Local Build + +Build the main analyzer binary: + +```bash +go build -o kantra main.go +``` + +### Building External Providers + +External providers (Java, Go, Python, Node.js, YAML) are built using Make: + +```bash +make build-external +``` + +This builds: +- `dotnet-provider` +- `golang-dependency-provider` +- `generic-external-provider` (handles Go, Python, Node.js) +- `java-external-provider` +- `yq-external-provider` (YAML) + +**Note for macOS users:** The `make build-external` target uses GNU sed syntax. If you encounter sed errors, you may need to manually run the sed commands with macOS syntax: + +```bash +sed -i '' 's/old/new/g' file +``` + +### Building Container Images + +Build the main analyzer container: + +```bash +podman build -t quay.io/konveyor/analyzer-lsp:latest -f Dockerfile . +``` + +Build external provider containers: + +```bash +# Builds all external providers +make build-external +``` + +## Testing Your Changes + +### Running Tests Locally + +Run the Go test suite: + +```bash +go test ./... +``` + +### Testing with Example Projects + +The `examples/` directory contains test projects for each language: + +- `examples/java/` - Java test projects +- `examples/golang/` - Go test projects +- `examples/nodejs/` - Node.js/TypeScript test projects +- `examples/python/` - Python test projects +- `examples/yaml/` - YAML/Kubernetes manifests + +### Running Analysis Locally + +Create a provider settings file (e.g., `provider_settings.json`): + +```json +{ + "name": "nodejs", + "binaryPath": "/usr/local/bin/typescript-language-server", + "address": "127.0.0.1:0", + "initConfig": [ + { + "location": "/path/to/your/project", + "providerSpecificConfig": { + "includedPaths": ["src/"], + "excludedPaths": ["node_modules/", "dist/"] + } + } + ] +} +``` + +Run analysis: + +```bash +./kantra \ + --provider-settings=provider_settings.json \ + --rules=rule-example.yaml \ + --output-file=output.yaml \ + --verbose=1 +``` + +## Container-Based Development + +Container-based testing is the **recommended approach** for comprehensive testing with all providers. + +### Why Use Containers? + +1. **Consistent Environment** - Same environment as CI/CD +2. **All Providers Together** - Test interactions between providers +3. **Resource Isolation** - Prevents provider memory/CPU conflicts +4. **Reproducible** - Matches production deployment + +### Container Testing Workflow + +This is the workflow used for regenerating `demo-output.yaml`: + +```bash +# 1. Build external providers with your changes +make build-external + +# 2. Build analyzer-lsp container image +podman build -t quay.io/konveyor/analyzer-lsp:latest -f Dockerfile . + +# 3. Run external providers pod +make run-external-providers-pod + +# 4. Build demo container image +podman build -f demo-local.Dockerfile -t localhost/testing:latest . + +# 5. Run demo image to generate output +make run-demo-image +``` + +### Provider Pod Architecture + +The `run-external-providers-pod` target creates a pod named `analyzer` with 6 containers: + +- `java-provider` - Port 14650 (Eclipse JDTLS) +- `generic-provider` - Port 14651 (Go/Python/Node.js) +- `dotnet-provider` - Port 14652 (.NET) +- `yq-provider` - Port 14653 (YAML) +- `golang-dep-provider` - Port 14654 (Go dependencies) +- `java-dep-provider` - Port 14655 (Java dependencies) + +All containers share the `test-data` volume for accessing example projects. + +### Resource Requirements + +**Minimum Resources for All Providers:** +- **RAM**: 12GB (8GB causes Java provider OOM) +- **CPU**: 4 cores +- **Disk**: 20GB + +Check your podman machine resources: + +```bash +podman machine info +``` + +Increase memory if needed: + +```bash +podman machine stop +podman machine set --memory 12288 # 12GB +podman machine start +``` + +### Cleaning Up Containers + +If you need to restart the provider pod: + +```bash +# Remove pod and volume +podman pod rm -f analyzer +podman volume rm test-data + +# Recreate pod +make run-external-providers-pod +``` + +## Adding New Rules + +Rules are defined in YAML files (e.g., `rule-example.yaml`). + +### Rule Structure + +```yaml +- ruleID: unique-rule-id-00000 + description: Brief description of what this rule detects + effort: 5 # Estimated effort to fix (1-10) + category: mandatory # mandatory, potential, or optional + labels: + - konveyor.io/source=source-technology + - konveyor.io/target=target-technology + when: + # Provider-specific condition (see below) + message: | + Detailed message explaining the issue and how to fix it. + + Before: + ``` + old code example + ``` + + After: + ``` + new code example + ``` + links: + - url: https://docs.example.com/migration + title: Migration Documentation +``` + +### Provider Types and When to Use Each + +#### builtin Provider (Text/Regex Matching) + +**Use for:** +- File content patterns +- Comments or documentation +- CSS/HTML patterns +- Configuration files +- When you need file filtering (`filePattern`) + +**Example:** +```yaml +when: + builtin.filecontent: + pattern: "oldFunction\\s*\\(" + filePattern: "\\.tsx?$" # Regex pattern for .ts and .tsx files +``` + +**File Pattern Examples:** +```yaml +filePattern: "\\.tsx?$" # .ts and .tsx files +filePattern: "\\.(js|ts)x?$" # .js, .jsx, .ts, .tsx files +filePattern: "\\.(css|scss)$" # .css and .scss files +filePattern: "\\.ya?ml$" # .yaml and .yml files +``` + +#### nodejs Provider (TypeScript/JavaScript Semantic Analysis) + +**Use for:** +- Function/class/variable references +- Import statements +- JSX component usage +- Semantic code analysis + +**Cannot find:** +- Class methods (use builtin) +- Object properties (use builtin) +- Type annotations (use builtin) +- JSX props (use builtin) + +**Example:** +```yaml +when: + nodejs.referenced: + pattern: "OldComponent" # Finds actual symbol references +``` + +**Important:** nodejs provider does NOT support `filePattern`. It automatically searches all TypeScript/JavaScript files. + +#### java Provider (Java Semantic Analysis) + +**Use for:** +- Java class/method/field references +- Annotations +- Import statements +- Package declarations + +**Example:** +```yaml +when: + java.referenced: + pattern: "org.example.OldClass" +``` + +#### Other Providers + +- **go.referenced** - Go symbol references +- **python.referenced** - Python symbol references +- **builtin.xml** - XML element/attribute matching +- **builtin.json** - JSON key/value matching +- **builtin.hasTags** - Check for specific tags + +### Combining Providers for Complete Coverage + +**Best Practice:** Use semantic providers (nodejs, java, go, python) for symbol references, and builtin provider for patterns they cannot detect. + +**Example: Detecting React Component Migration** + +```yaml +# nodejs provider - finds component imports and usage +- ruleID: old-button-component-00000 + when: + nodejs.referenced: + pattern: "OldButton" + message: | + OldButton component is deprecated. + Replace with NewButton. + +# builtin provider - finds prop usage (nodejs can't detect this) +- ruleID: old-button-variant-prop-00001 + when: + builtin.filecontent: + pattern: '