You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python开发的MyFancyApp中实现.gitignore式文件忽略打包功能?

How to Build a Python CLI Tool with .gitignore-Style Ignore Rules

Absolutely! You can totally build a .gitignore-style exclusion system for your MyFancyApp CLI tool. The build command will traverse your current directory, skip files/dirs listed in .MyFancyAppIgnore, and package everything else into a ZIP file. Let's walk through how to do this step by step.

Core Approach

We'll split this into three key tasks:

  1. Parse the .MyFancyAppIgnore file to extract exclusion rules (handling comments, empty lines, and wildcards like *, **, ?).
  2. Traverse the directory tree and filter out any paths that match the ignore rules.
  3. Package the remaining files into a ZIP archive.
  4. Wrap everything in a CLI using a library like click (cleaner than argparse for CLI tools).

Step-by-Step Implementation

We'll use click for the CLI interface. Install it via pip:

pip install click

2. Full Code Example

Create a file named MyFancyApp.py with the following code:

import click
import zipfile
from pathlib import Path
import fnmatch

def load_ignore_rules(ignore_file_path):
    """Load and parse the .MyFancyAppIgnore file."""
    rules = []
    if not ignore_file_path.exists():
        return rules
    
    with open(ignore_file_path, 'r') as f:
        for line in f:
            line = line.strip()
            # Skip comments and empty lines
            if not line or line.startswith('#'):
                continue
            # Store the rule (we'll handle path matching later)
            rules.append(line)
    return rules

def should_ignore(path, ignore_rules, root_dir):
    """Check if a given path should be ignored based on the rules."""
    # Convert path to relative path from root directory
    relative_path = str(path.relative_to(root_dir))
    
    # Check each rule against the relative path
    for rule in ignore_rules:
        # Handle recursive wildcards (**)
        if '**' in rule:
            # Split rule into parts before and after **
            prefix, suffix = rule.split('**', 1)
            if (fnmatch.fnmatch(relative_path, f"{prefix}*{suffix}") or
                fnmatch.fnmatch(relative_path, f"{prefix}*{suffix}/")):
                return True
        # Handle standard wildcards and exact matches
        elif fnmatch.fnmatch(relative_path, rule) or fnmatch.fnmatch(relative_path, f"{rule}/"):
            return True
    
    # Also exclude the ignore file itself and the output ZIP to avoid recursion
    if path == root_dir / '.MyFancyAppIgnore':
        return True
    return False

def build_project(root_dir, output_zip):
    """Traverse directory, filter files, and create ZIP archive."""
    ignore_file = root_dir / '.MyFancyAppIgnore'
    ignore_rules = load_ignore_rules(ignore_file)
    
    with zipfile.ZipFile(output_zip, 'w', zipfile.ZIP_DEFLATED) as zipf:
        # Walk through all files and directories
        for path in root_dir.rglob('*'):
            if should_ignore(path, ignore_rules, root_dir):
                continue
            # Add to ZIP: if it's a directory, add an entry (to preserve structure)
            if path.is_dir():
                # Add trailing slash to denote directory in ZIP
                zipf.write(path, arcname=str(path.relative_to(root_dir)) + '/')
            else:
                zipf.write(path, arcname=str(path.relative_to(root_dir)))
    
    click.echo(f"Successfully built {output_zip}!")

@click.group()
def cli():
    """MyFancyApp: A fancy CLI tool for packaging your project."""
    pass

@cli.command()
@click.option('--output', '-o', default='MyFancyApp.zip', help='Output ZIP file name.')
@click.option('--dir', default='.', help='Directory to package (default: current directory).')
def build(output, dir):
    """Package the project into a ZIP file, respecting .MyFancyAppIgnore rules."""
    root_dir = Path(dir).resolve()
    output_zip = Path(output).resolve()
    build_project(root_dir, output_zip)

if __name__ == '__main__':
    cli()

3. How It Works

  • Rule Parsing: The load_ignore_rules function reads .MyFancyAppIgnore, skips comments and empty lines, and stores valid exclusion rules.
  • Path Filtering: should_ignore converts each path to a relative path (so rules work correctly) and checks against wildcards using fnmatch. It handles recursive patterns like **/node_modules to ignore all node_modules directories anywhere in the tree.
  • ZIP Packaging: build_project uses zipfile to create a compressed ZIP, adding only non-ignored files and preserving directory structure.
  • CLI Interface: The click decorators turn the functions into a proper CLI, so you can run MyFancyApp build with optional flags for output path and target directory.

4. Using the Tool

  1. Create a .MyFancyAppIgnore file in your project directory with rules like:
    # Ignore virtual environments
    venv/
    __pycache__/
    
    # Ignore log files
    *.log
    
    # Ignore all temp directories anywhere
    **/temp/
    
  2. Run the build command:
    python MyFancyApp.py build
    
    Or specify a custom output:
    python MyFancyApp.py build -o my_project.zip
    

Optional Enhancements

  • Support Negation Rules: Add support for ! prefix to negate rules (e.g., !important.log to include a file that would otherwise be ignored). This requires adjusting the should_ignore function to handle priority of negation rules.
  • Use a Gitignore Parser Library: For full compatibility with .gitignore syntax (including edge cases), use the gitignore_parser library. Install it with pip install gitignore-parser and replace the rule loading and checking logic with:
    from gitignore_parser import parse_gitignore
    
    def load_ignore_rules(ignore_file_path):
        if not ignore_file_path.exists():
            return lambda path: False
        return parse_gitignore(ignore_file_path)
    
    def should_ignore(path, ignore_func, root_dir):
        return ignore_func(path) or path == root_dir / '.MyFancyAppIgnore'
    
    This handles all standard .gitignore features out of the box.

内容的提问来源于stack exchange,提问作者Tho

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 22:57:37