or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

index.mddocs/

grunt-contrib-copy

grunt-contrib-copy is a Grunt plugin that provides comprehensive file copying capabilities with advanced configuration options. It offers pattern-based file selection using glob patterns, content processing during copy operations, permission and timestamp preservation, and flexible destination path handling.

Package Information

  • Package Name: grunt-contrib-copy
  • Package Type: npm
  • Language: JavaScript (Node.js)
  • Installation: npm install grunt-contrib-copy --save-dev

Core Imports

This package is a Grunt plugin that registers itself when loaded:

// In your Gruntfile.js
grunt.loadNpmTasks('grunt-contrib-copy');

Basic Usage

// Gruntfile.js
module.exports = function(grunt) {
  grunt.initConfig({
    copy: {
      main: {
        files: [
          // Copy single files
          {src: 'src/app.js', dest: 'build/app.js'},
          
          // Copy with glob patterns
          {expand: true, cwd: 'src/', src: ['**/*.js'], dest: 'build/'},
          
          // Flatten directory structure
          {expand: true, flatten: true, src: ['src/**/*.css'], dest: 'build/css/'}
        ]
      }
    }
  });

  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.registerTask('default', ['copy']);
};

Architecture

grunt-contrib-copy is built around the standard Grunt plugin architecture:

  • Multi-task Registration: Registers a multi-task named 'copy' that can have multiple named targets
  • File Processing Pipeline: Processes file mappings using Grunt's file expansion and filtering system
  • Option Inheritance: Combines task-level and target-level options with sensible defaults
  • Grunt Integration: Leverages Grunt's built-in file utilities (grunt.file.copy, grunt.file.mkdir) for core operations
  • Progress Reporting: Provides verbose logging and summary statistics using Grunt's logging system

The plugin operates in phases: configuration expansion → file filtering → directory creation → file copying → permission/timestamp handling → progress reporting.

Key Internal Utilities:

  • Path Normalization: Automatically converts Windows backslashes to forward slashes for cross-platform compatibility
  • Destination Type Detection: Determines whether destination paths refer to files or directories based on trailing slashes
  • Timestamp Synchronization: Uses file comparison (file-sync-cmp) to preserve timestamps only when file contents are identical
  • Permission Management: Handles both copying existing permissions and setting specific permission modes

Capabilities

Task Registration

The plugin registers a multi-task named 'copy' that processes file copying operations.

// Grunt plugin registration (internal)
grunt.registerMultiTask('copy', 'Copy files.', function() { ... });

File Configuration

Configure source and destination files using Grunt's file mapping format.

interface FileConfig {
  /** Source file patterns (glob patterns supported) */
  src: string | string[];
  /** Destination path */
  dest: string;
  /** Enable dynamic file expansion */
  expand?: boolean;
  /** Change working directory for src matching */
  cwd?: string;
  /** File/directory filter function or filter name */
  filter?: 'isFile' | 'isDirectory' | ((filepath: string) => boolean);
  /** Flatten directory structure in destination */
  flatten?: boolean;
  /** Error on non-existent source files */
  nonull?: boolean;
  /** Original configuration (used internally) */
  orig?: {
    expand?: boolean;
  };
}

Task Options

Configure copy behavior with comprehensive options.

interface CopyOptions {
  /** File encoding for reading/writing files (default: grunt.file.defaultEncoding, typically 'utf8') */
  encoding?: string;
  /** Content transformation function */
  process?: (content: string, srcpath: string) => string;
  /** @deprecated Use process instead */
  processContent?: (content: string, srcpath: string) => string;
  /** Files to exclude from processing (glob patterns) */
  noProcess?: string | string[];
  /** @deprecated Use noProcess instead */
  processContentExclude?: string[];
  /** Preserve file timestamps during copy */
  timestamp?: boolean;
  /** Set file/directory permissions (boolean to copy existing, string/number for specific mode) */
  mode?: boolean | string | number;
}

Usage Example:

copy: {
  main: {
    options: {
      // Set specific encoding (utf8, ascii, binary, base64, hex, etc.)
      encoding: 'utf8',
      // Transform file contents during copy
      process: function(content, srcpath) {
        return content.replace(/{{VERSION}}/g, '1.0.0');
      },
      // Exclude binary files from processing
      noProcess: ['**/*.{png,gif,jpg,ico,psd}'],
      // Set file permissions
      mode: '0644',
      // Preserve timestamps
      timestamp: true
    },
    files: [
      {expand: true, cwd: 'src/', src: ['**'], dest: 'build/'}
    ]
  }
}

Content Processing

Transform file contents during the copy operation.

/**
 * Content transformation function
 * @param content - The file content as a string
 * @param srcpath - The source file path
 * @returns Transformed content string
 */
type ProcessFunction = (content: string, srcpath: string) => string;

Usage Example:

copy: {
  templates: {
    options: {
      process: function(content, srcpath) {
        // Replace placeholders with actual values
        return content
          .replace(/\{\{TITLE\}\}/g, 'My Application')
          .replace(/\{\{VERSION\}\}/g, grunt.option('version') || '1.0.0');
      }
    },
    files: [
      {src: 'templates/*.html', dest: 'build/', expand: true, flatten: true}
    ]
  }
}

File Filtering

Control which files are copied using built-in or custom filters.

/**
 * File filter function
 * @param filepath - The file path to test
 * @returns true to include the file, false to exclude
 */
type FilterFunction = (filepath: string) => boolean;

/** Built-in filter options */
type FilterOption = 'isFile' | 'isDirectory' | FilterFunction;

Usage Examples:

copy: {
  // Copy only files (exclude directories)
  filesOnly: {
    files: [
      {expand: true, src: ['src/**'], dest: 'build/', filter: 'isFile'}
    ]
  },
  
  // Custom filter function
  jsFiles: {
    files: [
      {
        expand: true,
        src: ['src/**'],
        dest: 'build/',
        filter: function(filepath) {
          return filepath.match(/\.js$/);
        }
      }
    ]
  }
}

Directory and Path Handling

Configure how directories and file paths are handled during copying.

interface PathHandlingOptions {
  /** Change working directory for source pattern matching */
  cwd?: string;
  /** Flatten directory structure (place all files in dest root) */
  flatten?: boolean;
  /** Dynamic file expansion for glob patterns */
  expand?: boolean;
}

Usage Examples:

copy: {
  // Copy maintaining directory structure
  preserve: {
    files: [
      {expand: true, cwd: 'src/', src: ['**'], dest: 'build/'}
    ]
  },
  
  // Flatten all files to destination root
  flatten: {
    files: [
      {expand: true, flatten: true, src: ['src/**/*.js'], dest: 'build/js/'}
    ]
  },
  
  // Copy single file tree
  tree: {
    files: [
      {expand: true, src: 'assets/**', dest: 'build/'}
    ]
  }
}

Permission and Timestamp Handling

Control file permissions and timestamp preservation.

interface FileAttributeOptions {
  /** File/directory permission mode */
  mode?: boolean | string | number;
  /** Preserve file access and modification times */
  timestamp?: boolean;
}

Usage Examples:

copy: {
  // Copy existing permissions
  withPerms: {
    options: {
      mode: true
    },
    files: [
      {expand: true, src: ['scripts/**'], dest: 'build/'}
    ]
  },
  
  // Set specific permissions
  executable: {
    options: {
      mode: '0755'
    },
    files: [
      {src: 'bin/myapp', dest: 'build/bin/myapp'}
    ]
  },
  
  // Preserve timestamps
  timestamped: {
    options: {
      timestamp: true
    },
    files: [
      {expand: true, src: ['docs/**'], dest: 'build/docs/'}
    ]
  }
}

Error Handling

Control error behavior for missing files and other issues.

interface ErrorHandlingOptions {
  /** Generate error for non-existent source files */
  nonull?: boolean;
}

Usage Example:

copy: {
  strict: {
    options: {
      nonull: true  // Will error if source files don't exist
    },
    files: [
      {src: 'required-file.txt', dest: 'build/required-file.txt'}
    ]
  }
}

Task Execution

When the copy task runs, it:

  1. Processes each file configuration in the files array
  2. Expands glob patterns and applies filters
  3. Creates necessary destination directories
  4. Copies or processes each file according to options
  5. Sets permissions and timestamps if configured
  6. Reports progress with file and directory counts

Example output:

Running "copy:main" (copy) task
Created 3 directories, copied 12 files

Done, without errors.

Common Patterns

Build Asset Pipeline

copy: {
  // Copy and process HTML templates
  html: {
    options: {
      process: function(content, srcpath) {
        return content.replace(/\{\{env\}\}/g, process.env.NODE_ENV || 'development');
      }
    },
    files: [
      {expand: true, cwd: 'src/', src: ['**/*.html'], dest: 'build/'}
    ]
  },
  
  // Copy static assets without processing
  assets: {
    options: {
      noProcess: ['**/*.{png,jpg,gif,svg,woff,ttf}']
    },
    files: [
      {expand: true, cwd: 'src/assets/', src: ['**'], dest: 'build/assets/'}
    ]
  },
  
  // Copy and flatten vendor libraries
  vendor: {
    files: [
      {expand: true, flatten: true, src: ['node_modules/*/dist/*.min.js'], dest: 'build/vendor/'}
    ]
  }
}

Development vs Production

copy: {
  dev: {
    options: {
      // Fast copying for development
      timestamp: false
    },
    files: [
      {expand: true, cwd: 'src/', src: ['**'], dest: 'build/'}
    ]
  },
  
  prod: {
    options: {
      // Optimized copying for production
      process: function(content, srcpath) {
        // Minify or transform content
        return content.replace(/\s+/g, ' ').trim();
      },
      timestamp: true,
      mode: '0644'
    },
    files: [
      {expand: true, cwd: 'src/', src: ['**/*.{js,css,html}'], dest: 'build/'}
    ]
  }
}