Skip to main content

Automatically adds or updates SPDX license and copyright headers in source files.

Project description

Python License

PyPI version Python versions License Tests

One command to add SPDX license headers to all your source files. Works best with pre-commit hooks.

What It Does

Automatically adds SPDX-compliant license headers to your source files.

For Python files:

# SPDX-License-Identifier: Apache-2.0
# Copyright (C) 2025  Your Name

def your_code():
    pass

For JavaScript/TypeScript/Go/Rust:

// SPDX-License-Identifier: MIT
// Copyright (C) 2025  Your Company

function yourCode() {}

For CSS/HTML:

/* SPDX-License-Identifier: Apache-2.0 */
/* Copyright (C) 2025  Your Name */

body { margin: 0; }

Key Features

  • Supports 50+ file types including Python, JavaScript, TypeScript, Go, Rust, Java, C/C++, Swift, Kotlin, Ruby, Shell, SQL, and more
  • Automatically updates copyright year ranges (e.g., 2023 becomes 2023-2025 when modified)
  • Check mode for CI/CD integration to ensure all files have headers
  • Respects .licenseignore and .gitignore files automatically
  • Preserves shebang lines in executable scripts
  • Handles multiple comment styles (hash, slash, dash, block comments)

Supported Languages

Hash comments (#): Python, Shell (bash/zsh/fish), Ruby, Perl, R, YAML, TOML, CMake

Slash comments (//): JavaScript, TypeScript, Go, Rust, Java, C/C++, Swift, Kotlin, C#, PHP, Scala, Objective-C, Gradle, Groovy, SCSS, Sass, Less

Dash comments (--): SQL, Lua, Haskell, Elm

Block comments: CSS (/* */), HTML/XML/SVG (<!-- -->)

Special files: Dockerfile, Makefile, Jenkinsfile, Vagrantfile, Rakefile, Gemfile, Podfile, Fastfile, CMakeLists.txt, and more

Installation

pipx install python-license

Or with pip:

pip install python-license

Usage

Command Line

Basic syntax:

license <license-id> "<author>" [options]

Examples:

# Check files without modifying (dry-run)
license Apache-2.0 "John Doe" --check

# Add/update headers in specific directory
license MIT "Jane Smith" --fix --dir src/

# Use custom ignore file
license GPL-3.0 "ACME Corp" --ignore-file .licenseignore --fix

# Process specific files only
license Apache-2.0 "Your Name" --fix file1.py file2.js

# Set custom copyright year
license MIT "Your Company" --fix --year 2024

Pre-commit Hook (Recommended)

Add to your .pre-commit-config.yaml:

repos:
  - repo: https://github.com/eznix86/python-license
    rev: v1.0.1
    hooks:
      - id: license-headers
        args: ['--check', 'Apache-2.0', 'Your Name']

For automatic fixing on commit:

repos:
  - repo: https://github.com/eznix86/python-license
    rev: v1.0.1
    hooks:
      - id: license-headers
        args: ['--fix', 'Apache-2.0', 'Your Name']

See .pre-commit-config.yaml for a complete example.

Options

Option Description
--check Check files without modifying (default mode)
--fix Add or update headers in files
--dir DIR Root directory to process (default: current directory)
--year YEAR Copyright year (default: current year)
--no-recursive Don't process subdirectories
--verbose, -v Show all processed files
--ignore-file FILE Path to ignore file (default: .licenseignore or .gitignore)
files Specific files to process (overrides --dir)

Ignore Files

Create a .licenseignore file to exclude specific files or directories:

# Ignore patterns (similar to .gitignore)
*.min.js
*.min.css
generated/*
vendor/
third_party/
build/
dist/

# Negate patterns (don't ignore these)
!important.min.js

If no .licenseignore exists, the tool automatically uses .gitignore patterns.

See .licenseignore for an example.

FAQ

Does it overwrite existing headers?

No, it intelligently updates them. If a file already has an SPDX header, it will:

  • Update the license identifier if changed
  • Update the copyright year range (e.g., 20232023-2025)
  • Preserve the existing header structure

How does it handle copyright years?

The tool automatically manages copyright year ranges:

  • First added: Copyright (C) 2025 Your Name
  • After modification in 2026: Copyright (C) 2025-2026 Your Name
  • If already current: no change

Can I use it in CI/CD?

Yes! Use --check mode to fail the build if any files are missing headers:

# GitHub Actions example
- name: Check license headers
  run: license Apache-2.0 "Your Name" --check

This returns exit code 1 if any files need updating.

What files are excluded by default?

The tool automatically excludes common build artifacts and dependencies:

  • Version control: .git/, .svn/, .hg/
  • Dependencies: node_modules/, vendor/, third_party/
  • Build outputs: build/, dist/, target/, __pycache__/
  • Minified files: *.min.js, *.min.css
  • Lock files: *.lock, *.sum, go.mod
  • Config files: *.json, *.toml, *.yaml

Can I use custom SPDX license identifiers?

Yes! Use any valid SPDX license identifier. Common examples:

  • MIT
  • Apache-2.0
  • GPL-3.0-or-later
  • BSD-3-Clause
  • ISC

See SPDX License List for all valid identifiers.

Does it work with monorepos?

Yes! You can:

  • Run it on the entire repo
  • Use --dir to target specific packages
  • Use different .licenseignore files in different directories
  • Process specific files only

Contributing

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

Please make sure to update tests as appropriate.

License

This project is licensed under the Apache License 2.0.

See the NOTICE file for additional information.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

python_license-1.2.2.tar.gz (26.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

python_license-1.2.2-py3-none-any.whl (15.8 kB view details)

Uploaded Python 3

File details

Details for the file python_license-1.2.2.tar.gz.

File metadata

  • Download URL: python_license-1.2.2.tar.gz
  • Upload date:
  • Size: 26.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.5

File hashes

Hashes for python_license-1.2.2.tar.gz
Algorithm Hash digest
SHA256 80993c3f958d91cfd3802dbb84a8fa220164e1da76296168ac553dc6d6dc8f41
MD5 5c2a05a36817fe8fe48b2a1ec32345db
BLAKE2b-256 55455d412ce4418a8a02a3981de4ec8d5cbafe23715de5458c38c367a34ff2c5

See more details on using hashes here.

File details

Details for the file python_license-1.2.2-py3-none-any.whl.

File metadata

File hashes

Hashes for python_license-1.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 146ecf6efe47a419d790d88b61fe5332db333f2649bcc886b283e3eee17548ce
MD5 04cff0b8e65e1b8c4c846994832abbd6
BLAKE2b-256 ae42ac1de5ad9cc1a3df754faf70ad264ea3d9cd5764248d1dd9c8c78c99efca

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page