{"id":3886,"library":"ast-grep-cli","title":"ast-grep-cli","description":"ast-grep-cli is a Python package that provides a command-line interface (CLI) wrapper for the powerful `ast-grep` tool. `ast-grep` enables structural search and rewrite of code across various programming languages using abstract syntax tree (AST) patterns. The project is actively developed with frequent minor releases, often weekly or bi-weekly, incorporating new features, bug fixes, and language support updates. The current version is 0.42.1.","status":"active","version":"0.42.1","language":"en","source_language":"en","source_url":"https://github.com/ast-grep/ast-grep","tags":["AST","static analysis","refactoring","code quality","CLI","structural search","code rewrite"],"install":[{"cmd":"pip install ast-grep-cli","lang":"bash","label":"Install latest version"}],"dependencies":[],"imports":[{"note":"While `ast_grep_cli` provides a `main` function as its console entry point, the primary and recommended way to interact with `ast-grep` programmatically from Python is via `subprocess.run()` to execute the `sg` command. The `main` function essentially wraps this `subprocess.run()` call.","symbol":"main","correct":"from ast_grep_cli import main"}],"quickstart":{"code":"import subprocess\nimport os\nimport json\n\n# Create a dummy file for demonstration\ndummy_js_code = \"\"\"\nfunction greet(name) {\n    console.log(\"Hello, \" + name);\n}\ngreet(\"World\");\n\"\"\"\nwith open(\"example.js\", \"w\") as f:\n    f.write(dummy_js_code)\n\ntry:\n    # Example 1: Search for 'console.log($$$)' pattern and get JSON output\n    print(\"--- Searching for console.log statements (JSON output) ---\")\n    command_search = [\n        \"sg\",\n        \"run\",\n        \"--pattern\",\n        \"console.log($$$)\",\n        \"--lang\",\n        \"javascript\",\n        \"--path\",\n        \"example.js\",\n        \"--json\" # Use JSON output for programmatic parsing\n    ]\n    search_result = subprocess.run(\n        command_search,\n        capture_output=True,\n        text=True,\n        check=False # Do not raise CalledProcessError if no matches (returns non-zero exit code)\n    )\n    print(f\"Search Exit Code: {search_result.returncode}\")\n    if search_result.stdout:\n        try:\n            json_output = json.loads(search_result.stdout)\n            print(\"Parsed JSON Output:\", json.dumps(json_output, indent=2))\n        except json.JSONDecodeError:\n            print(\"Stdout (not valid JSON):\", search_result.stdout)\n    if search_result.stderr:\n        print(f\"Search Stderr:\\n{search_result.stderr}\")\n\n    # Example 2: Perform a dry-run rewrite from 'console.log' to 'alert'\n    print(\"\\n--- Performing a dry-run rewrite (stdout output) ---\")\n    command_rewrite_dry_run = [\n        \"sg\",\n        \"run\",\n        \"--pattern\",\n        \"console.log($$$)\",\n        \"--rewrite\",\n        \"alert($$$)\",\n        \"--lang\",\n        \"javascript\",\n        \"--path\",\n        \"example.js\",\n        \"--dry-run\" # Show changes without modifying the file\n    ]\n    rewrite_result = subprocess.run(\n        command_rewrite_dry_run,\n        capture_output=True,\n        text=True,\n        check=False\n    )\n    print(f\"Rewrite Dry-Run Exit Code: {rewrite_result.returncode}\")\n    print(f\"Rewrite Dry-Run Stdout:\\n{rewrite_result.stdout}\")\n    if rewrite_result.stderr:\n        print(f\"Rewrite Dry-Run Stderr:\\n{rewrite_result.stderr}\")\n\nexcept FileNotFoundError:\n    print(\"Error: 'sg' command not found. Ensure ast-grep-cli is installed and in your PATH.\")\nexcept Exception as e:\n    print(f\"An unexpected error occurred: {e}\")\nfinally:\n    if os.path.exists(\"example.js\"):\n        os.remove(\"example.js\")\n","lang":"python","description":"This quickstart demonstrates how to use `ast-grep-cli` from Python by invoking the `sg` command via `subprocess.run()`. It shows both a search operation with JSON output and a dry-run rewrite example. Always prefer using `--json` output for robust parsing of `ast-grep` results in scripts."},"warnings":[{"fix":"Update scripts to explicitly check for `subprocess.run().returncode`. Handle non-zero return codes (e.g., 1) for 'no matches' scenarios if appropriate for your logic. For robust programmatic parsing, always use the `--json` output option, as its structure is more stable than CLI text output regardless of the exit code.","message":"The exit code behavior of `sg` changed in versions 0.40.2 and 0.40.5. Previously, `sg` would often return 0 even if no matches were found. Now, it correctly returns a non-zero exit code (typically 1) when no matches are found, indicating a 'failure' to find results. This affects scripting where the absence of matches might have been interpreted as success.","severity":"breaking","affected_versions":">=0.40.2"},{"fix":"Pin `ast-grep-cli` to a specific minor version (e.g., `ast-grep-cli==0.42.1`) in your production environments and CI/CD pipelines. Review the official GitHub release notes thoroughly when planning an upgrade to a newer minor version. Always consult `sg --help` for the exact options available in your installed version.","message":"Due to the rapid development of the underlying `ast-grep` tool, CLI arguments, supported languages, and default behaviors can evolve quickly between minor versions. This means scripts or configurations written for one version might behave differently or break with another.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Interact with `ast-grep` in Python scripts by executing the `sg` command using `subprocess.run()` and parsing its standard output. The `--json` output format is highly recommended for machine-readable results.","message":"The `ast-grep-cli` Python package primarily serves as an installer for the `sg` command-line executable. There is no public, stable Python API designed for programmatic interaction as a traditional library (i.e., by importing classes/functions to manipulate ASTs directly within Python).","severity":"gotcha","affected_versions":"All versions"},{"fix":"Ensure your `sgconfig.yml` files conform to the latest specification by testing with your target `ast-grep-cli` version. Consult the official `ast-grep` documentation and schema for the most current configuration options and syntax. Version control your `sgconfig.yml` files alongside your code.","message":"The format and validation rules for `ast-grep` configuration files (e.g., `sgconfig.yml`) can change across versions. For instance, support for `.yaml` extension was fixed in 0.40.0, and unknown keys for patterns were rejected in 0.40.2, indicating stricter parsing.","severity":"breaking","affected_versions":"All versions, especially before 0.40.2"},{"fix":"If a specific language's support is critical for your use case, thoroughly test your `ast-grep` patterns and rewrites against the desired language in your chosen `ast-grep-cli` version. Consult the `ast-grep` documentation and `sg --list-langs` for the most current list of supported languages and their parser statuses.","message":"Support for specific programming languages and their respective parsers can fluctuate or be refined across `ast-grep` versions. For example, Dart support was re-added in version 0.42.1, indicating that language availability or parser quality can change.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-11T00:00:00.000Z","next_check":"2026-07-10T00:00:00.000Z"}