or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/pypi-pantsbuild-pants-contrib-spindle

Pants build system plugin for generating Scala code from Thrift IDL files using Spindle

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
pypipkg:pypi/pantsbuild.pants.contrib.spindle@1.0.x

To install, run

npx @tessl/cli install tessl/pypi-pantsbuild-pants-contrib-spindle@1.0.0

index.mddocs/

Pantsbuild Pants Contrib Spindle

A Pants build system plugin that enables automatic generation of Scala libraries from Thrift IDL files using Foursquare's Spindle code generator. This plugin integrates Spindle's thrift-to-Scala compilation into the Pants build pipeline, providing seamless dependency management and incremental compilation for large-scale projects.

Package Information

  • Package Name: pantsbuild.pants.contrib.spindle
  • Language: Python
  • Installation: pip install pantsbuild.pants.contrib.spindle
  • Plugin Type: Pants build system contrib plugin

Core Imports

from pants.contrib.spindle.register import build_file_aliases, register_goals
from pants.contrib.spindle.targets.spindle_thrift_library import SpindleThriftLibrary
from pants.contrib.spindle.tasks.spindle_gen import SpindleGen

Basic Usage

Plugin Registration

This plugin is typically registered automatically when installed. In Pants configuration:

# pants.ini or pants.toml
[DEFAULT]
# The plugin provides 'spindle_thrift_library' target type and 'spindle' task

BUILD File Usage

# In a BUILD file
spindle_thrift_library(
  name='user-service-thrift',
  sources=['user.thrift', 'profile.thrift'],
  dependencies=[
    '3rdparty:spindle-runtime',
  ],
)

Command Line Usage

# Generate Scala code from Thrift files
pants gen.spindle src/main/thrift:user-service-thrift

# The generated Scala and Java files will be placed in the workspace
# under appropriate namespace directories

Example Thrift File

namespace java com.example.user

typedef string UserId

struct User {
  1: required UserId id
  2: required string name
  3: optional string email
}

service UserService {
  User getUser(1: UserId userId)
  list<User> listUsers()
}

Capabilities

Plugin Registration

Registration functions that integrate the plugin with the Pants build system.

def build_file_aliases():
    """
    Returns build file aliases for the spindle plugin.
    
    Returns:
        BuildFileAliases: Aliases containing the 'spindle_thrift_library' target type
    """

def register_goals():
    """
    Registers the 'spindle' task under the 'gen' goal.
    
    Installs the SpindleGen task to be executed when 'gen.spindle' is invoked.
    """

Target Types

Target type for defining Thrift libraries that will be compiled to Scala using Spindle.

class SpindleThriftLibrary(ExportableJvmLibrary):
    """
    A Scala library generated from Spindle IDL files.
    
    This target type represents Thrift files that should be compiled to Scala
    using the Spindle code generator. Inherits from ExportableJvmLibrary to
    provide JVM library capabilities.
    """
    
    def __init__(self, *args, **kwargs):
        """
        Initialize a SpindleThriftLibrary target.
        
        Automatically adds 'scala', 'codegen', and 'synthetic' labels to the target.
        
        Args:
            *args: Variable arguments passed to parent ExportableJvmLibrary
            **kwargs: Keyword arguments passed to parent ExportableJvmLibrary
        """

Code Generation Task

The main task that performs Thrift-to-Scala code generation using Spindle.

class SpindleGen(NailgunTask):
    """
    Task that generates Scala code from Thrift files using Spindle.
    
    This task processes SpindleThriftLibrary targets, executes the Spindle
    code generator, and creates synthetic Scala and Java library targets
    with the generated code.
    """
    
    @classmethod
    def product_types(cls):
        """
        Returns the product types produced by this task.
        
        Returns:
            list: ['scala'] - indicates this task produces Scala code
        """
    
    @classmethod
    def register_options(cls, register):
        """
        Register command-line options for the SpindleGen task.
        
        Args:
            register: Option registration function
            
        Registers:
            --runtime-dependency: Runtime dependencies for generated code
            --spindle-codegen tool: Spindle code generator tool configuration
        """
    
    @property
    def spindle_classpath(self):
        """
        Get the classpath for the Spindle code generator tool.
        
        Returns:
            list: Classpath entries for spindle-codegen tool
        """
    
    @property
    def synthetic_target_extra_dependencies(self):
        """
        Get additional dependencies for synthetic targets.
        
        Returns:
            set: Set of dependency targets from runtime-dependency option
        """
    
    @property
    def namespace_out(self):
        """
        Get the output directory for generated code.
        
        Returns:
            str: Path to output directory (workdir/src/jvm)
        """
    
    def codegen_targets(self):
        """
        Get all targets that need code generation.
        
        Returns:
            list: List of SpindleThriftLibrary targets
        """
    
    def sources_generated_by_target(self, target):
        """
        Calculate the source files that will be generated for a target.
        
        Args:
            target: SpindleThriftLibrary target
            
        Returns:
            list: List of paths to generated source files
        """
    
    def execute_codegen(self, targets):
        """
        Execute the Spindle code generation process.
        
        Args:
            targets: List of SpindleThriftLibrary targets to process
            
        Raises:
            TaskError: If code generation fails
        """
    
    def execute(self):
        """
        Main execution method for the task.
        
        Orchestrates the entire code generation process:
        1. Identifies targets needing generation
        2. Executes code generation for invalid targets
        3. Creates synthetic Scala and Java library targets
        4. Manages dependencies and build graph updates
        5. Updates artifact cache if enabled
        """

Utility Functions

Helper functions for calculating generated file paths and parsing Thrift files.

def calculate_genfiles(source):
    """
    Calculate which files will be generated from a Thrift source file.
    
    Parses the Thrift file to extract namespace information and determines
    the output file paths that Spindle will generate.
    
    Args:
        source (str): Path to Thrift source file relative to build root
        
    Returns:
        list: List of generated file basenames (without .scala/.java extensions)
        
    Raises:
        TaskError: If no Java namespace is found in the source file
    """

def calculate_scala_record_genfiles(namespace, source):
    """
    Calculate generated file basenames for Scala records.
    
    Args:
        namespace (str): Java namespace from Thrift file
        source (str): Path to source Thrift file
        
    Returns:
        list: List of generated file paths (basenames, add .scala/.java for full path)
    """

Types

Build System Integration Types

BuildFileAliases: 
    """
    Pants build system type for registering target aliases.
    Contains mappings from target names to target classes.
    """

TaskRegistrar:
    """
    Pants build system type for registering tasks under goals.
    Provides the task() method for goal registration.
    """

ExportableJvmLibrary:
    """
    Base class for JVM library targets that can be exported.
    Provides standard JVM library functionality and export capabilities.
    """

NailgunTask:
    """
    Base class for tasks that execute JVM tools via Nailgun.
    Provides JVM tool execution and classpath management.
    """

Configuration Types

JarDependency:
    """
    Represents a JAR dependency with org, name, and revision.
    Used to specify the Spindle codegen tool dependency.
    """

# Default tool configuration
SPINDLE_CODEGEN_DEFAULT = JarDependency(
    org='com.foursquare',
    name='spindle-codegen-binary_2.10', 
    rev='3.0.0-M7'
)

Error Handling

The plugin raises TaskError exceptions in the following cases:

  • Missing namespace: When a Thrift file lacks a required Java namespace declaration
  • Code generation failure: When the Spindle code generator returns a non-zero exit code
  • File system errors: When output directories cannot be created or accessed

Plugin Configuration

Default Settings

  • Runtime dependency: ['3rdparty:spindle-runtime']
  • Spindle version: 3.0.0-M7 (com.foursquare:spindle-codegen-binary_2.10)
  • Templates:
    • Scala: scala/record.ssp
    • Java: javagen/record.ssp

Options

# Configure runtime dependencies
pants gen.spindle --runtime-dependency=path/to:runtime-dep

# Configure JVM options for code generation
pants gen.spindle --jvm-options="-Xmx2g -XX:MaxPermSize=256m"

Generated Output

The plugin generates:

  1. Scala files: .scala files containing Scala case classes and companion objects
  2. Java files: .java files with Java representations for interoperability
  3. Synthetic targets: Scala and Java library targets with proper dependency management
  4. Namespace structure: Files organized according to Thrift namespace declarations

Generated files follow the pattern:

  • Input: com/example/user.thrift with namespace java com.example.user
  • Output: src/jvm/com/example/user/user.scala and src/jvm/com/example/user/java_user.java