Skip to main content
Version: Next

Configuration Guide

LicenseOps can be configured via a YAML config file, CLI flags, or a combination of both. CLI flags always take precedence over the config file.

Config File

By default, lops looks for .licenseops.yaml in the current working directory. Use -c to specify a different path.

Config File Resolution

ScenarioBehavior
.licenseops.yaml exists in cwdLoaded automatically — no flags needed
.licenseops.yaml doesn't existSilently falls back to built-in defaults, no error
-c path/to/config.yamlUses that file — errors if not found
-c /dev/nullEmpty config — only CLI flags and defaults apply
note

If .licenseops.yaml doesn't exist, lops silently uses defaults — no error. This is intentional so you can use CLI flags without a config file.

This means lops works in two modes:

  • With config: commit .licenseops.yaml to your repo, run lops check / lops fix with no flags
  • Without config: pass everything via flags — lops check -l MIT -o "Your Name" .

Minimal Config

license: MIT
copyright-holder: 'Jane Doe'

Full Config

# Required
license: Apache-2.0
copyright-holder: 'Acme Corp'

# Optional — defaults shown
year: 2026 # defaults to current year
format: spdx # spdx | reuse | apache-long | gpl-long | custom
header-template: '' # only used with format: custom

# File selection
paths: # directories/files to scan (default: ["."])
- '.'
- 'libs/'

# Exclusion patterns (doublestar glob syntax)
exclude:
- 'vendor/**'
- 'node_modules/**'
- '**/*.pb.go'
- '**/*_generated.*'
- '**/testdata/**'

# Behavior
skip-generated: true # skip files with "DO NOT EDIT" / "@generated" markers
gitignore: true # respect .gitignore patterns

CLI Flags

FlagShortDefaultDescription
--license-lnoneSPDX license ID or expression
--owner-ononeCopyright holder
--format-fspdxHeader format
--year-yCurrent yearCopyright year
--config-c.licenseops.yamlConfig file path
--verbose-vfalseShow every file
--dry-runfalsePreview changes (fix/remove)
--difffalseShow unified diff (fix only, implies dry-run)
--excluded-onlyfalseInvert scan; process only files matching exclude patterns (remove only)
--outputtextOutput format: text, json, sarif

No flag is required on the command line — all values can be provided via the config file instead. The tool validates that required values are present (from either source) before running.

Defaults and Fallbacks

Every setting is resolved through a three-layer chain:

CLI flag  →  config file  →  built-in default

If a CLI flag is set, it wins. Otherwise the config file value is used. If neither provides a value, the built-in default applies. If there is no default and no value is provided, validation errors with a clear message.

Detailed default values:

SettingBuilt-in DefaultNotes
licensenone — requiredMust be set via config or -l flag. Errors if missing.
copyright-holdernone — optionalIf omitted, SPDX format uses 1-line mode (no copyright line). Required for reuse, apache-long, gpl-long formats.
formatspdxCan be overridden in config or with -f flag.
yearCurrent yearAuto-detected. Override with -y for a specific year.
config.licenseops.yamlLooked up in cwd. If the file doesn't exist, silently skipped — no error.
paths["."]Scans current directory. Config can set multiple paths. CLI args override entirely.
excludevendor/**, node_modules/**, .git/**, third_party/**, .licenseops.yamlConfig patterns are appended to these defaults, not replaced.
skip-generatedtrueSkips files with DO NOT EDIT / @generated markers.
gitignoretrueRespects .gitignore patterns from the project root.
header-templatenoneOnly required when format: custom.

Required vs Optional by Format

Settingspdxreuseapache-longgpl-longcustom
licenseRequiredRequiredMust be Apache-2.0Must be GPL/LGPL/AGPLRequired
copyright-holderOptional (omit for 1-line)RequiredRequiredRequiredOptional
header-templateRequired

If a required field is missing, lops exits with code 2 and a message like:

Error: license is required (set via config or --license flag)
Error: copyright-holder is required for 'reuse' format
Error: 'apache-long' format requires license: Apache-2.0 (got "MIT")

Flag Behavior Details

-o "" (explicit empty owner): Clears the copyright holder even if the config file sets one. This forces SPDX 1-line mode.

# Config has copyright-holder, but you want 1-line mode for this run:
lops fix -l MIT -o "" .

-l (license): Accepts single IDs (MIT) or expressions (Apache-2.0 OR MIT). Validated against the SPDX license list.

warning

Deprecated GNU IDs like bare GPL-2.0 or GPL-3.0 will trigger a deprecation warning. Use the explicit -only or -or-later suffix instead: GPL-3.0-only, GPL-3.0-or-later.

Paths (positional args): If paths are passed as arguments, they replace the paths from config entirely (not appended).

# Config says paths: ["."], but only scan src/:
lops check src/

# Scan multiple specific paths:
lops check src/ libs/ cmd/

Merge Rules Summary

SettingMerge behavior
licenseFlag replaces config
copyright-holderFlag replaces config (including -o "" to clear)
formatFlag replaces config
yearFlag replaces config
pathsCLI args replace config (not appended)
excludeConfig appends to built-in defaults (not replaced)
skip-generatedConfig replaces default
gitignoreConfig replaces default

Exclude Patterns

LicenseOps uses doublestar glob syntax for exclusion patterns.

Pattern Syntax

PatternMatches
*.pyPython files in the root directory only
**/*.pyPython files in any directory
vendor/**Everything under the vendor directory
**/*_test.goAll Go test files
src/**/*.{js,ts}JS and TS files under src/
**/generated_*.goFiles starting with generated_ anywhere
docs/**/*.mdMarkdown files under docs/

Excluding by File Type

exclude:
- '**/*.py' # all Python files
- '**/*.java' # all Java files
- '**/*.{js,jsx}' # all JS and JSX files

Excluding Directories

exclude:
- 'vendor/**'
- 'node_modules/**'
- 'third_party/**'
- 'build/**'
- 'dist/**'
- '.git/**'

Excluding Generated Code

exclude:
- '**/*.pb.go' # protobuf generated Go
- '**/*_generated.go' # codegen output
- '**/*.gen.ts' # generated TypeScript
- '**/generated/**' # entire generated directory
tip

In addition to exclude patterns, setting skip-generated: true (the default) will automatically skip files containing Code generated ... DO NOT EDIT or @generated markers — no exclude pattern needed for those.

Default Excludes

These are always excluded even without config:

  • vendor/**
  • node_modules/**
  • .git/**
  • third_party/**
  • .licenseops.yaml

User-defined exclude patterns are added on top of these defaults — they never replace them.

Cleaning Up Headers in Excluded Files

If you've added new entries to your exclude: list and want to strip the license headers that are still present in those files, use:

lops remove --excluded-only --dry-run    # preview
lops remove --excluded-only # actually strip

--excluded-only inverts the scanner: it walks the entire tree but only processes files that match a pattern from your config's exclude: block. Built-in defaults (.git/**, vendor/**, node_modules/**, third_party/**, .licenseops.yaml) and gitignore filtering are bypassed in this mode so the cleanup targets exactly what you declared excluded.

This flag is only available on remove; it does not exist on check or fix, since validating or fixing excluded files would defeat the purpose of excluding them.

SPDX License Expressions

The license field accepts full SPDX expressions, not just single IDs.

Single License

license: MIT

Dual License (choice)

license: 'Apache-2.0 OR MIT'

Produces: // SPDX-License-Identifier: Apache-2.0 OR MIT

Multiple Licenses (all apply)

license: 'Apache-2.0 AND MIT'

Complex Expressions

license: 'Apache-2.0 AND (MIT OR GPL-2.0-only)'

License with Exception

license: 'GPL-3.0-only WITH Classpath-exception-2.0'

Or-Later (non-GNU)

license: 'EPL-1.0+'

GNU Convention

GNU licenses use -only / -or-later suffixes:

license: GPL-3.0-only       # exactly v3.0
license: GPL-3.0-or-later # v3.0 or any later version

Using bare GPL-2.0 or GPL-3.0 will trigger a deprecation warning.

Format-Specific Config

SPDX 1-Line Mode

Omit copyright-holder to use SPDX-only headers:

license: MIT
# no copyright-holder → 1-line mode

Produces: // SPDX-License-Identifier: MIT

Apache Long Format

license: Apache-2.0
copyright-holder: 'Acme Corp'
format: apache-long

Requires license: Apache-2.0 — any other license will error.

GPL Long Format

license: GPL-3.0-only
copyright-holder: 'Free Soft Corp'
format: gpl-long

Requires a GPL/LGPL/AGPL license ID.

Custom Template

license: MIT
copyright-holder: 'Acme Corp'
format: custom
header-template: 'headers/my-header.tmpl'

See Custom Templates for template syntax.

See Also