dpk
An alternative package manager for Dart that enhances the standard dart pub commands with extra features like script running and dependency patching. dpk acts as a wrapper around the standard Dart tooling, allowing you to use the commands you are already familiar with.
Features
- Familiar Commands: Implements
get,add,remove,upgrade, anddowngradecommands that mirrordart pub. - Script Runner: Define and run custom scripts from your
dpk.yamlfile usingdpk run. - Dependency Patching: A powerful feature to manage and apply patches to your dependencies, ideal for monorepos or when you need to test a fix before a package is updated.
Installation
Install dpk globally using the following command:
dart install dpk
For Dart versions before 3.10, use:
dart pub global activate dpk
Setup
A minimal dpk project requires two files:
pubspec.yaml - Standard Dart package file:
name: my_package
environment:
sdk: ^3.8.0
dpk.yaml - dpk configuration file:
version: ^X.Y.Z
The version field is required and specifies which dpk version your project is compatible with. This ensures all team members use a compatible version.
Usage
dpk is designed to be a drop-in replacement for many dart pub commands.
Managing Dependencies
-
dpk get: Gets the dependencies for the current package. -
dpk add <package>: Adds a new dependency to yourpubspec.yaml.# Add a dependency dpk add http # Add a dev dependency dpk add dev:lints -
dpk remove <package>: Removes a dependency from yourpubspec.yaml. -
dpk upgrade: Upgrades the dependencies to their latest versions. -
dpk update: Alias forupgrade- upgrades dependencies to their latest versions. -
dpk downgrade: Downgrades dependencies to the oldest possible versions.
Running Scripts
You can define custom scripts in a dpk.yaml file at the root of your project. Note: A dpk.yaml file is required to use dpk.
dpk.yaml example:
version: ^X.Y.Z # Required: dpk version constraint
scripts:
analyze: dart analyze
test: dart test
Run a script using dpk run:
dpk run analyze
Script Hooks
Scripts can have pre and post hooks that run before and after any script or built-in command. Hooks use the format pre:<script> and post:<script>:
Example with hooks:
scripts:
# Get command hooks (works with built-in dpk get command)
pre:get: echo "Starting dependency resolution..."
post:get: echo "Dependencies resolved!"
# Build command hooks
pre:build: dart run build_runner clean
build: dart run build_runner build -d
post:build: echo "Build completed successfully"
# Watch command can inherit build hooks
watch:
runHooksFrom: build
command: dart run build_runner watch -d
When you run dpk run build, it executes:
pre:buildhook (if defined)buildcommandpost:buildhook (if defined)
Note: Hooks work for any script you define, as well as built-in dpk commands like get, add, remove, etc.
Environment Variables
You can set environment variables for scripts using the env section:
scripts:
build:
command: dart compile exe bin/main.dart -o build/app
env:
DART_VM_OPTIONS: '-Denv=production'
LOG_LEVEL: verbose
Injected Environment Variables
dpk automatically injects the following environment variables into scripts:
| Variable | Description | Available In |
|---|---|---|
DPK_ROOT |
Absolute path to the workspace root directory | Scripts with runInPackages |
Example using DPK_ROOT:
scripts:
check-root:
command: echo "Workspace root is $DPK_ROOT"
runInPackages:
- 'packages/*'
Patching Dependencies
The patch command set allows you to create, apply, and manage patches for your dependencies. This is particularly useful when you need to make temporary changes to a package without forking it.
Note: Patching requires
mode: projectin yourdpk.yamlto install packages locally (see mode below).
1. Initialize Patching
First, initialize the patching environment. This will create a pub_packages directory and set up a git repository to track changes.
dpk patch init
This command must be run after fetching dependencies with dpk get. It creates a git repository in the pub_packages directory and commits the initial state of your dependencies.
Important: Make sure to exclude the pub_packages directory from version control and analysis:
- Add to
.gitignore:
pub_packages/
- Add to
analysis_options.yamlto prevent analyzer performance issues:
analyzer:
exclude:
- pub_packages/**
Excluding pub_packages from analysis is crucial - without this, the Dart analyzer will consume excessive resources analyzing all dependency code, leading to slow performance and potential crashes.
2. Modify Your Dependencies
Navigate into the pub_packages directory and make any required changes to the dependency source code.
3. Generate Patches
Once you have made your changes, generate patch files:
dpk patch generate
This command compares the modified dependency code against the initial state and creates .patch files in the patches directory.
4. Apply Patches
To apply existing patches to your dependencies (e.g., after a fresh dpk get), use the apply command:
dpk patch apply
This command will apply all .patch files found in the patches directory to the corresponding packages in pub_packages. This is useful in a CI/CD environment or when another developer on your team needs to get your changes.
Note: If you haven't run dpk patch init yet, you'll need to run it first to set up the patching environment.
Configuration (dpk.yaml)
The dpk.yaml file allows for advanced configuration of scripts and workspace settings. Below is a complete reference of all available options:
Complete Configuration Example
# Required: dpk version constraint
version: ^X.Y.Z
# Operational mode
mode: global # or 'project' - see mode section below
# Sort pubspec.yaml keys on dpk get
sort_pubspec: true
# Workspace glob patterns (for monorepos)
workspace:
- packages/*
- apps/*
# Script definitions
scripts:
# Simple format
analyze: dart analyze
format: dart format .
# Advanced format with all options
test:
command: dart test
description: Run unit tests
env:
TEST_ENV: integration
API_URL: http://localhost:8080
runInPackages: # Run in specific workspace packages
- 'packages/*'
- 'apps/*'
runHooksFrom: build # Inherit hooks from another script
build:
command: dart compile exe bin/main.dart
# Hook definitions
pre:build: echo "Starting build at $(date)"
post:build: |
echo "Build completed"
ls -la bin/
pre:test: dart analyze
post:test: dart format --set-exit-if-changed .
# Catalog configuration (for monorepos/workspaces)
# Note: Requires root pubspec.yaml to have name: '_'
catalog:
# Environment constraints
environment:
sdk: '>=3.0.0 <4.0.0'
flutter: '>=3.10.0' # Optional Flutter SDK constraint
# Package version applied to workspace packages
version: 1.2.3
# Package metadata (supports template variables - see below)
homepage: https://example.com/DPK_PACKAGE_NAME
repository: https://github.com/username/repo/tree/main/DPK_PACKAGE_PATH
issue_tracker: https://github.com/username/repo/issues
documentation: https://pub.dev/documentation/DPK_PACKAGE_NAME/DPK_PACKAGE_VERSION/
funding:
- https://github.com/sponsors/DPK_PACKAGE_NAME
# Publishing configuration
publish_to: none # or a custom pub server URL
# Package categorization for pub.dev
topics:
- dart
- cli
- package-manager
# Supported platforms for pub.dev
platforms:
linux:
macos:
# Dependency resolution type
resolution: workspace # or 'hosted' for standard resolution
# Shared dependencies across workspace (applies to both dependencies and dev_dependencies)
dependencies:
http: ^1.1.0
path: ^1.9.0
lints: ^3.0.0
test: ^1.24.0
Configuration Properties
version (Required)
Specifies the required dpk version constraint. dpk will refuse to run if the installed version doesn't satisfy this constraint.
version: ^X.Y.Z
This ensures all team members use a compatible version of dpk.
mode
Specifies the operational mode for dpk.
global(default): Packages are installed using the standarddart pub getbehavior (to the global pub cache).project: Packages are installed to the localpub_packagesdirectory for patching and local modifications.
sort_pubspec
When set to true, dpk will sort pubspec.yaml files when running dpk get:
- Top-level keys are sorted according to a standard order:
name,description,version,resolution,publish_to,homepage,repository,issue_tracker,documentation,topics,screenshots,funding,platforms,false_secrets,ignored_advisories,environment,dependencies,dev_dependencies,dependency_overrides,executables,flutter - Unknown keys not in the standard order are placed after their preceding key from the original file
- Package names within
dependencies,dev_dependencies, anddependency_overridesare sorted alphabetically - Comments (inline and standalone) are preserved
- Blank lines are added between logical groups
sort_pubspec: true
If dpk get finds the old sortPubspec key, it rewrites it to
sort_pubspec. During parsing, both keys are accepted so older config keeps
working until migration runs.
workspace
Defines glob patterns for workspace packages. This is an alternative to defining the workspace field directly in pubspec.yaml.
workspace:
- packages/*
- apps/**
dpk will expand these patterns and write the resolved paths to the root pubspec.yaml.
scripts
Defines custom commands that can be executed with dpk run <script_name>.
Simple format:
scripts:
analyze: dart analyze
Advanced format with options:
scripts:
test:
command: dart test # Required
description: Run unit tests # Optional help/documentation text
env: # Optional environment variables
CI: 'true'
LOG_LEVEL: 'verbose'
runInPackages: # For monorepos - glob patterns
- 'packages/*'
runHooksFrom: build # Inherit pre/post hooks
Script Options:
command(Required): The shell command to executedescription: Optional help text for documenting the scriptenv: Environment variables to set before running the scriptrunInPackages: Glob patterns for workspace packages where the script should runrunHooksFrom: Name of another script to inherit hooks fromscripts: Hook target list forbeforeandafterall: Whentrueonbeforeorafter, match every hookable command
catalog
The catalog property is a powerful feature for managing monorepos. It allows you to define shared configurations across multiple packages, ensuring consistency for dependencies, metadata, and more.
To enable the catalog, the name of your root pubspec.yaml must be _.
dpk get applies catalog values to pubspec files. The workspace root package
only receives environment and dependency updates. Workspace packages receive
the full package metadata set.
Catalog Properties:
environment: Replaces theenvironmentsection. Supports keys such assdkandflutter.version: Sets the workspace packageversion.publish_to: Setspublish_to, for examplenoneor a custom pub server URL.homepage: Setshomepage. Supports template variables.repository: Setsrepository. Supports template variables.issue_tracker: Setsissue_tracker. Supports template variables.documentation: Setsdocumentation. Supports template variables.topics: Ensures listed topics exist. Existing package topics are preserved and missing catalog topics are appended.funding: Sets thefundingURL list. Supports template variables.platforms: Sets theplatformsmap, using standard pubspec platform keys such asandroid,ios,linux,macos,web, andwindows.resolution: Sets the pub workspace resolution, usuallyworkspace.dependencies: Updates matching existing entries in bothdependenciesanddev_dependencies. Missing dependencies are not added.
Catalog does not currently manage name, description, screenshots,
false_secrets, ignored_advisories, executables, flutter,
dependency_overrides, or a separate dev_dependencies catalog section.
Template Variables:
The following template variables can be used in homepage, repository,
issue_tracker, documentation, and funding fields:
Template variables are expanded separately for each workspace package during
dpk get:
| Variable | Expands to |
|---|---|
DPK_PACKAGE_PATH |
The workspace package path relative to the workspace root, such as packages/core |
DPK_PACKAGE_NAME |
The package name from that package's pubspec.yaml, such as core |
DPK_PACKAGE_VERSION |
The catalog version when one is configured; otherwise the package's existing pubspec version |
Variables can also be written with a shell-style $ prefix, such as
$DPK_PACKAGE_NAME.
Example with template variables:
catalog:
version: 1.2.3
homepage: https://example.com/DPK_PACKAGE_NAME
repository: https://github.com/user/repo/tree/main/DPK_PACKAGE_PATH
documentation: https://pub.dev/documentation/DPK_PACKAGE_NAME/DPK_PACKAGE_VERSION/
For a package at packages/core with name: core, this expands to:
homepage: https://example.com/core
repository: https://github.com/user/repo/tree/main/packages/core
documentation: https://pub.dev/documentation/core/1.2.3/
When you run dpk get in a workspace with a catalog, dpk automatically updates each package's pubspec.yaml with the catalog configuration, replacing template variables with package-specific values.
Advanced Features
Workspace Support
dpk automatically detects workspace configurations by looking for a workspace field in parent pubspec.yaml files. This enables:
- Running scripts across multiple packages with
runInPackages - Sharing dependencies and configuration via catalog
- Consistent versioning across the workspace
Automatic Workspace Detection
dpk searches up the directory tree to find workspace roots, allowing you to run commands from any subdirectory within a workspace.
Complex Script Chaining
Scripts can be chained and share hooks using runHooksFrom:
scripts:
ci:
command: echo "Running CI"
runHooksFrom: test # Inherits pre:test and post:test
pre:test: dart analyze
post:test: dart format --set-exit-if-changed .
Troubleshooting
Common Issues
- "dpk.yaml not found": A
dpk.yamlfile is required in your project root (or workspace root for monorepos) - "'version' is required in dpk.yaml": Add a
versionfield with a semver constraint (e.g.,version: ^X.Y.Z) - "dpk version X.X.X does not satisfy required version constraint": Update dpk with
dart install dpk(Dart 3.10+) ordart pub global activate dpk - Patches not applying: Ensure you've run
dpk patch initfirst and that the patches directory exists - Workspace not detected: Check that parent directories have a valid
pubspec.yamlwith aworkspacefield - Environment variables not substituting: Verify the variable is exported in your shell environment
- Scripts not found: Ensure
dpk.yamlis in the project root
Libraries
- commands/get_command
- commands/init_command
- commands/parent_commands/patch_command
- commands/pub_passthrough_command
- commands/run_command
- commands/skills_command
- commands/subcommands/patch/apply_command
- commands/subcommands/patch/generate_command
- commands/subcommands/patch/init_command
- config/config
- config/data/catalog
- config/data/config_data
- config/data/dependency
- config/data/dpk_config
- config/data/dpk_workspace_environment
- config/data/scripts
- constants/embedded_dpk_skill
- constants/pubspec
- core/command_runner
- core/constants
- core/injection_container
- core/mixins/config_mixin
- core/mixins/hook_runner_mixin
- core/mixins/process_handler_mixin
- core/mixins/pub_env_mixin
- core/shell
- core/types
- utils/cache_directory
- utils/catalog_comment_utils
- utils/catalog_utils
- utils/collection
- utils/command_checker
- utils/extensions/debug_extensions
- utils/extensions/string_extensions
- utils/globals/global_args
- utils/globals/global_patch_args
- utils/globals/global_pub_args
- utils/pubspec_sorter
- utils/terminal_log_util
- utils/terminal_title
- utils/version_output
- utils/workspace