Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ testdata/src/
├── generated/ # Generated file detection
├── internal/config # Internal package detection tests
├── unexported/ # Tests for -unexported flag
└── ignore/ # Tests for -ignore flag
├── ignore/ # Tests for -ignore flag
└── jsontest/ # Tests for -output=json flag
```

Test annotations use `// want "message"` comments to assert expected diagnostics:
Expand Down
49 changes: 40 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,20 @@ positionless ./...
# Analyze specific package
positionless ./pkg/mypackage

# Apply suggested fixes automatically
positionless -fix ./...

# Include generated files (excluded by default)
positionless -generated ./...

# Apply suggested fixes automatically
positionless -fix ./...
# Fix structs with unexported fields in internal packages
positionless -fix -internal ./...

# Skip specific struct types
positionless -ignore="ConfigTest,*Mock" ./...

# JSON output for tooling integration
positionless -output=json ./... 2>&1
```

### With go vet
Expand Down Expand Up @@ -186,8 +195,21 @@ jobs:
| `path` | Path to analyze | `./...` |
| `fix` | Apply suggested fixes automatically | `false` |
| `include-generated` | Include generated files in analysis | `false` |
| `include-unexported` | Include structs with unexported fields in fixes | `false` |
| `include-internal` | Auto-allow unexported fields in `internal/` packages | `false` |
| `ignore` | Comma-separated patterns to skip (e.g., `ConfigTest,*Mock`) | `` |
| `output` | Output format: `text` or `json` | `text` |
| `version` | Version of positionless to use | `latest` |

#### Action Outputs

| Output | Description |
|--------|-------------|
| `findings-count` | Number of positional struct literals found |
| `fixed-count` | Number of fixes applied (when fix is enabled) |
| `exit-code` | Exit code from the analyzer (0=success, 3=findings) |
| `version` | Version of positionless used |

#### Example Output

Here's what the GitHub Action output looks like when it detects positional struct literals:
Expand Down Expand Up @@ -284,10 +306,11 @@ The analyzer:

1. Scans your Go code for struct literal initialization
2. Identifies positional initialization patterns
3. Suggests fixes that convert to named field initialization
4. Can automatically apply fixes with the `-fix` flag
5. Preserves your original values and formatting
6. Skips generated files by default (use `-generated` to include them)
3. Reports all positional struct literals as warnings
4. Suggests fixes that convert to named field initialization
5. Can automatically apply fixes with the `-fix` flag
6. Preserves your original values and formatting
7. Skips generated files by default (use `-generated` to include them)

### Flags

Expand All @@ -297,12 +320,20 @@ The analyzer:
| `-generated` | Include generated files in analysis |
| `-unexported` | Include structs with unexported fields in fixes |
| `-internal` | Auto-allow unexported fields in `internal/` packages |
| `-ignore=PATTERN` | Skip structs matching pattern (comma-separated) |
| `-output=FORMAT` | Output format: `text` (default) or `json` |
| `-ignore=PATTERN` | Skip structs matching pattern (comma-separated, supports globs) |
| `-output=FORMAT` | Output format: `text` (default) or `json` (golangci-lint compatible) |

> [!TIP]
> Use `-internal` when analyzing your own internal packages where you control all the code

### Exit codes

| Code | Meaning |
|------|---------|
| 0 | No issues found |
| 1 | Error occurred |
| 3 | Issues found (useful for CI pipelines) |

## Example

Given this code:
Expand Down Expand Up @@ -330,7 +361,7 @@ cfg := Config{
```

> [!IMPORTANT]
> The analyzer only processes exported fields to respect Go's visibility rules
> By default, the analyzer reports all positional structs but only auto-fixes those with exported fields. Use `-unexported` or `-internal` to enable fixes for structs with unexported fields.

## License

Expand Down
30 changes: 29 additions & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,22 @@ inputs:
description: 'Include generated files in analysis'
required: false
default: 'false'
include-unexported:
description: 'Include structs with unexported fields in fixes'
required: false
default: 'false'
include-internal:
description: 'Auto-allow unexported fields in internal/ packages'
required: false
default: 'false'
ignore:
description: 'Comma-separated patterns to skip (e.g., ConfigTest,*Mock)'
required: false
default: ''
output:
description: 'Output format: text or json'
required: false
default: 'text'
version:
description: 'Version of positionless to use (default: latest)'
required: false
Expand Down Expand Up @@ -94,7 +110,19 @@ runs:
if [ "${{ inputs.include-generated }}" == "true" ]; then
FLAGS="$FLAGS -generated"
fi

if [ "${{ inputs.include-unexported }}" == "true" ]; then
FLAGS="$FLAGS -unexported"
fi
if [ "${{ inputs.include-internal }}" == "true" ]; then
FLAGS="$FLAGS -internal"
fi
if [ -n "${{ inputs.ignore }}" ]; then
FLAGS="$FLAGS -ignore=${{ inputs.ignore }}"
fi
if [ "${{ inputs.output }}" != "text" ]; then
FLAGS="$FLAGS -output=${{ inputs.output }}"
fi

echo "Running: positionless $FLAGS ${{ inputs.path }}"

# Run analyzer and capture output
Expand Down