{"id":7116,"library":"craft-parts","title":"Craft Parts","description":"Craft Parts is a Python package that provides a reusable and extensible framework for defining, processing, and organizing software components into deployment-ready filesystems. It supports various source types and build plugins, enabling declarative management of complex build processes and dependencies. The library is actively developed by Canonical and is a core component for tools like Snapcraft and Charmcraft, with regular releases.","status":"active","version":"2.32.0","language":"en","source_language":"en","source_url":"https://github.com/canonical/craft-parts","tags":["build system","packaging","snapcraft","charmcraft","lifecycle management","devops"],"install":[{"cmd":"pip install craft-parts","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"Command-line client builder framework.","package":"craft-cli"},{"reason":"Application-level crafting utilities.","package":"craft-application"},{"reason":"Manages software builds in containers.","package":"craft-providers"},{"reason":"Manages interaction with software package repositories.","package":"craft-archives"},{"reason":"Provides Python interfaces for advanced grammar.","package":"craft-grammar"},{"reason":"Platform-specific utilities for crafting.","package":"craft-platforms"},{"reason":"Storage utilities for crafting artifacts.","package":"craft-store"},{"reason":"Determines Linux distribution information.","package":"distro"},{"reason":"Data validation and settings management using Python type hints.","package":"pydantic"},{"reason":"YAML parser and emitter for Python.","package":"pyyaml"},{"reason":"HTTP library for making web requests.","package":"requests"},{"reason":"Utility belt for the Requests library.","package":"requests-toolbelt"},{"reason":"Simple, fast, extensible JSON encoder/decoder.","package":"simplejson"},{"reason":"Backports and experimental type hints.","package":"typing-extensions"},{"reason":"Validation for various types of data.","package":"validators"},{"reason":"Classes without boilerplate.","package":"attrs"},{"reason":"JSON Schema validation.","package":"jsonschema"},{"reason":"Required for package metadata and setup utilities.","package":"setuptools"}],"imports":[{"note":"Manages the lifecycle of parts (pull, build, stage, prime).","symbol":"LifecycleManager","correct":"from craft_parts.lifecycle import LifecycleManager"},{"note":"Represents a component to be built within the crafting process.","symbol":"Part","correct":"from craft_parts.models import Part"},{"note":"Access to various build plugins (e.g., poetry_plugin, nil_plugin).","symbol":"plugins","correct":"from craft_parts import plugins"},{"note":"Provides information about a part during its lifecycle.","symbol":"PartInfo","correct":"from craft_parts.models import PartInfo"}],"quickstart":{"code":"import os\nimport pathlib\nfrom craft_parts.models import PartSpec, Part\nfrom craft_parts.lifecycle import LifecycleManager, Step\n\n# Create a dummy project directory\nproject_dir = pathlib.Path('./my-craft-project')\nproject_dir.mkdir(exist_ok=True)\n\n# Create a simple parts.yaml content\nparts_yaml_content = '''\nparts:\n  hello:\n    plugin: dump\n    source: hello.txt\n'''\n(project_dir / 'parts.yaml').write_text(parts_yaml_content)\n(project_dir / 'hello.txt').write_text('Hello from Craft Parts!')\n\n# Define the part specification programmatically\npart_spec = PartSpec(\n    name=\"hello\",\n    part=Part(\n        plugin=\"dump\",\n        source=\"hello.txt\"\n    )\n)\n\n# Initialize LifecycleManager\nlcm = LifecycleManager(\n    parts={part_spec.name: part_spec.part},\n    application_name=\"my-craft-app\",\n    project_dir=project_dir,\n    build_dir=project_dir / 'build',\n    stage_dir=project_dir / 'stage',\n    prime_dir=project_dir / 'prime',\n    cache_dir=project_dir / '.cache'\n)\n\n# Plan and execute the full lifecycle\nactions = lcm.plan(Step.PRIME)\nwith lcm.action_executor() as aex:\n    aex.execute(actions)\n\nprint(f\"Project built to: {project_dir / 'prime'}\")\nprint(f\"Content of staged file: {(project_dir / 'prime' / 'hello.txt').read_text()}\")\n","lang":"python","description":"This quickstart demonstrates programmatically defining a simple 'hello' part that uses the 'dump' plugin to copy a source file. It then initializes a `LifecycleManager` to plan and execute the full crafting process (pull, build, stage, prime) within a temporary project structure, printing the output file."},"warnings":[{"fix":"Thoroughly review the 'Parts lifecycle' and 'Part properties' sections in the official documentation. Use `craft_parts --dry-run` to inspect the planned steps before a full build.","message":"Understanding the part lifecycle (pull, overlay, build, stage, prime) is crucial. Misconfiguring `source`, `build-packages`, `stage-packages`, or `prime` properties can lead to unexpected build outputs or missing files in the final artifact.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Refer to the 'Create a plugin' and 'Override a part's default build behavior' guides. Use verbose logging and inspect environment setup scripts if commands fail to execute as expected. Test custom scripts incrementally.","message":"When developing custom plugins or overriding build steps, ensure correct environment variable propagation and command execution within the isolated build environments. Pathing issues are common.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Always select a plugin that matches your project's build system. If no suitable plugin exists, use `plugin: nil` and define `override-pull`, `override-build`, `override-stage`, etc., as needed in your `parts.yaml` or `Part` definition.","message":"The `dump` plugin simply copies source files. If your part requires compilation or complex build steps, you must specify an appropriate plugin (e.g., `autotools`, `cmake`, `poetry`, `go`) or provide `override-build` instructions.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Ensure every part has a `plugin` property set to a valid, installed plugin name (e.g., `python`, `nil`, `dump`, `autotools`). Check the documentation for available plugins. Example: `plugin: python` or `plugin: dump`.","cause":"A part in your configuration (`parts.yaml` or `Part` object) either omits the `plugin` property or specifies a plugin name that doesn't exist or isn't recognized.","error":"InvalidPluginError: The part '<part_name>' didn't define a plugin and the part name is not a valid plugin name."},{"fix":"Examine the detailed output/stderr from the build step for specific errors (e.g., missing dependencies, compilation errors). Debug your build script locally within a similar environment. Adjust your part's `build-packages` or `override-build` properties.","cause":"The build commands executed by the specified plugin for the part returned a non-zero exit code, indicating a build failure. This often points to issues in your project's `configure`, `make`, `install` steps or `override-build` script.","error":"PluginBuildFailedError: Plugin build script for part '<part_name>' failed at runtime."},{"fix":"Verify the package name is correct and available for your target distribution. Check network connectivity. For `build-packages`, ensure your environment has access to the necessary repositories.","cause":"A package listed in `build-packages` or `stage-packages` could not be installed in the isolated environment, often due to a typo in the package name, an unavailable package in the distribution, or network issues preventing package downloads.","error":"OverlayPackageInstallationError: Failed to install an overlay package '<package_name>'."},{"fix":"Confirm that the `source` specified for the part points to an existing file or directory. Check paths referenced in `organize` or `prime` properties. Ensure file system permissions allow `craft-parts` to write to the target directories.","cause":"An operation attempting to copy or link files (e.g., during `pull`, `stage`, or `prime` steps) failed because the source file/directory was not found, or there was a permissions issue at the destination.","error":"FailedToCopyError: Failed to copy or link a file tree from '<source_path>' to '<destination_path>'."}]}