changepacks-cli 0.2.14

CLI interface and commands for changepacks
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
<p align="center">
  <img src="media/logo.svg" alt="changepacks logo" width="200"/>
</p>

[![Crates.io](https://img.shields.io/crates/v/changepacks)](https://crates.io/crates/changepacks)
[![PyPI](https://img.shields.io/pypi/v/changepacks)](https://pypi.org/project/changepacks)
[![npm bundle size](https://img.shields.io/bundlephobia/minzip/@changepacks/cli)](https://bundlephobia.com/package/@changepacks/cli)
[![npm version](https://img.shields.io/npm/v/@changepacks/cli)](https://www.npmjs.com/package/@changepacks/cli)
[![npm downloads](https://img.shields.io/npm/dm/@changepacks/cli)](https://www.npmjs.com/package/@changepacks/cli)
[![license](https://img.shields.io/github/license/changepacks/changepacks)](LICENSE)
[![CI](https://img.shields.io/github/actions/workflow/status/changepacks/changepacks/CI.yml?branch=main)](https://github.com/changepacks/changepacks/actions)
[![codecov](https://img.shields.io/codecov/c/github/changepacks/changepacks?logo=codecov)](https://codecov.io/gh/changepacks/changepacks)
[![GitHub stars](https://img.shields.io/github/stars/changepacks/changepacks?style=social&label=Star)](https://github.com/changepacks/changepacks)
[![GitHub forks](https://img.shields.io/github/forks/changepacks/changepacks?style=social&label=Fork)](https://github.com/changepacks/changepacks/fork)
[![GitHub issues](https://img.shields.io/github/issues/changepacks/changepacks)](https://github.com/changepacks/changepacks/issues)
[![GitHub pull requests](https://img.shields.io/github/issues-pr/changepacks/changepacks)](https://github.com/changepacks/changepacks/pulls)
[![GitHub last commit](https://img.shields.io/github/last-commit/changepacks/changepacks)](https://github.com/changepacks/changepacks/commits/main)
[![Rust](https://img.shields.io/badge/Rust-1.72%2B-orange.svg)](https://rust-lang.org/)
[![Python](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/)
[![Node.js](https://img.shields.io/badge/Node.js-18%2B-green.svg)](https://nodejs.org/)
[![Bun](https://img.shields.io/badge/Bun-latest-000000.svg)](https://bun.sh)

# changepacks ๐Ÿ“ฆ

A unified version management and changelog tool for multi-language monorepos.

## Overview

**changepacks** is a Rust-powered CLI tool that brings consistent version management and changelog generation to polyglot projects. Inspired by [changesets](https://github.com/changesets/changesets), it extends beyond JavaScript to natively support Node.js, Python, Rust, and Dart ecosystems with a single, fast, and reliable tool.

### Why changepacks?

- ๐ŸŒ **True Multi-Language Support** - Manage versions across Node.js, Python, Rust, and Dart with unified workflow
- ๐Ÿš€ **Rust Performance** - Fast, parallel operations with single binary distribution
- ๐Ÿ”— **Smart Dependencies** - Automatic dependency resolution with topological sorting for publishing
- ๐Ÿ’พ **Format Preservation** - Respects language conventions (JSON indentation, TOML formatting, YAML structure)
- ๐ŸŒณ **Git-Native** - Uses git history for intelligent change detection
- ๐ŸŽฏ **Developer-Friendly** - Interactive CLI with colored output, tree views, and clear error messages

## Recent Improvements

- ๐Ÿ”— **Workspace Dependency Updates** - Automatically updates `workspace:*` dependencies in package.json when referenced packages are updated
- โš™๏ธ **Update On Rules** - Configure `updateOn` in config to automatically trigger updates for dependent packages (e.g., bridge packages)
- โœจ **Enhanced Readability** - Patch lists now display with newlines instead of commas for better visibility
- ๐Ÿ“ฆ **Dependency Sorting** - Topological sort ensures packages publish in correct order
- ๐ŸŽจ **Improved Output** - Tree view with colorized status and dependency visualization
- ๐Ÿ”ง **Format Preservation** - Maintains your file formatting (indentation, newlines) across all updates

## Features

- ๐Ÿš€ **Multi-language Support** - Native support for Node.js, Python, Rust, and Dart with workspace detection
- ๐Ÿ“ **Changepack Logs** - Track version updates with timestamped logs and detailed notes
- ๐Ÿ”„ **Automated Updates** - Smart version bumping with workspace dependency updates
- ๐Ÿ”— **Dependency Resolution** - Topological sorting ensures dependencies publish before dependents
- โšก **Fast CLI** - Async Rust implementation with parallel operations
- ๐ŸŽฏ **Project Detection** - Automatic discovery of packages and workspaces via git
- ๐Ÿ“Š **Status & Visualization** - Tree view of dependencies with change markers
- ๐Ÿ’พ **Format Preservation** - Maintains indentation, newlines, and file formatting
- ๐Ÿงช **Testing Support** - Dry-run mode for updates and publishing
- ๐Ÿ”ง **Configurable** - Custom publish commands, ignore patterns, and base branch

## Supported Languages & Package Managers

| Language | Package Manager | File | Status |
|----------|----------------|------|--------|
| **Node.js** | npm, pnpm, yarn | `package.json` | โœ… Supported |
| **Python** | pip, uv | `pyproject.toml` | โœ… Supported |
| **Rust** | Cargo | `Cargo.toml` | โœ… Supported |
| **Dart** | pub | `pubspec.yaml` | โœ… Supported |

## Installation

Choose your preferred package manager:

### Windows
```bash
winget install Changepacks.Changepacks
```

### Rust (Cargo)
```bash
cargo install changepacks
```

### Python
```bash
# pip
pip install changepacks

# uv (recommended)
uv add changepacks
uvx changepacks
```

### Node.js
```bash
# npm
npm install @changepacks/cli
npx @changepacks/cli

# pnpm
pnpm install @changepacks/cli
pnpm dlx @changepacks/cli

# yarn
yarn install @changepacks/cli

# bun
bun install @changepacks/cli
bunx @changepacks/cli
```

### Requirements

- Git repository (for project detection)
- Rust 1.91+ (for building from source)

### Build from Source

```bash
git clone https://github.com/changepacks/changepacks.git
cd changepacks
cargo build --release
```

The binary will be available at `target/release/changepacks` (or `target/release/changepacks.exe` on Windows).

## Usage

### Quick Start

1. **Initialize** changepacks in your repository:
```bash
changepacks init
```

2. **Create a changepack** when you make changes:
```bash
changepacks
```
This opens an interactive session to select changed projects and write release notes.

3. **Update versions** from changepack logs:
```bash
changepacks update
```

4. **Publish** packages in dependency order:
```bash
changepacks publish
```

### Typical Workflow

```bash
# 1. Check which projects have changed
changepacks check --tree

# 2. Create a changepack log for your changes
changepacks
# โ†’ Select projects (Major/Minor/Patch)
# โ†’ Write changelog notes

# 3. Preview version updates
changepacks update --dry-run

# 4. Apply version updates
changepacks update

# 5. Test publishing
changepacks publish --dry-run

# 6. Publish to registries
changepacks publish
```

### Check Project Status

View all projects with change detection:

```bash
changepacks check              # List all projects
changepacks check --tree       # Show dependency tree
changepacks check --filter workspace  # Only workspaces
changepacks check --filter package    # Only packages
changepacks check --remote     # Compare with remote branch
```

### Update Versions

Apply version bumps from changepack logs:

```bash
changepacks update              # Interactive confirmation
changepacks update --dry-run    # Preview without applying
changepacks update --yes        # Skip confirmation
```

### Publish Packages

Publish packages to their respective registries:

```bash
changepacks publish
```

Options:

```bash
changepacks publish --dry-run           # Preview what would be published without actually publishing
changepacks publish --yes               # Skip confirmation prompts
changepacks publish --format json       # Output results in JSON format
changepacks publish --remote            # Use remote branch for change detection
```

The publish command will:
1. Discover all projects in your workspace
2. Show which projects will be published
3. Execute the publish command for each project (using language-specific defaults or custom commands from config)

Default publish commands by language:
- **Node.js**: `npm publish`
- **Python**: `uv publish`
- **Rust**: `cargo publish`
- **Dart**: `dart pub publish`

### Check Config

View the loaded changepacks config (from `.changepacks/config.json`):

```bash
changepacks config
```

This prints the merged and defaulted configuration, for example:

```json
{
  "ignore": [
    "**/*",
    "!crates/changepacks/Cargo.toml",
    "!bridge/node/package.json",
    "!bridge/python/pyproject.toml"
  ],
  "baseBranch": "main",
  "latestPackage": "crates/changepacks/Cargo.toml",
  "publish": {
    "node": "npm publish",
    "python": "uv publish",
    "rust": "cargo publish",
    "dart": "dart pub publish",
    "bridge/node/package.json": "npm publish --access public"
  },
  "updateOn": {
    "crates/changepacks/Cargo.toml": ["bridge/node/package.json", "bridge/python/pyproject.toml"]
  }
}
```

You can edit `.changepacks/config.json` to customize:
- Files/projects to ignore (`ignore`) using glob patterns (default: empty).
- The base branch to compare against for changes (`baseBranch`, default: `"main"`).
- The default main package for versioning (`latestPackage`, optional).
- Custom publish commands (`publish`):
  - Set language-specific commands using language keys: `"node"`, `"python"`, `"rust"`, `"dart"`.
  - Set project-specific commands using relative paths (e.g., `"bridge/node/package.json"`).
  - If not specified, default commands are used (see Publish Packages section).
- Dependency rules for forced updates (`updateOn`):
  - Key: glob pattern for trigger packages (e.g., `"crates/*/Cargo.toml"`).
  - Value: list of package file paths that must be updated when trigger matches.
  - When a package matching the trigger pattern is updated, all dependent packages will also be marked for update.
  - Useful for bridge packages that wrap core libraries (e.g., when core Rust crate updates, automatically update Node.js and Python bindings).

If the config file is missing or empty, sensible defaults are used.

### Default Command

Running `changepacks` without arguments starts an interactive session to select projects and create a changepack log.

## Project Structure

```
changepacks/
โ”œโ”€โ”€ crates/
โ”‚   โ”œโ”€โ”€ cli/          # CLI interface and commands
โ”‚   โ”œโ”€โ”€ core/         # Core types and traits
โ”‚   โ”œโ”€โ”€ node/         # Node.js project support
โ”‚   โ”œโ”€โ”€ python/       # Python project support
โ”‚   โ”œโ”€โ”€ rust/         # Rust project support
โ”‚   โ”œโ”€โ”€ dart/         # Dart project support
โ”‚   โ””โ”€โ”€ utils/        # Utility functions
โ”œโ”€โ”€ examples/         # Example projects for testing
โ”œโ”€โ”€ Cargo.toml        # Workspace configuration
โ””โ”€โ”€ README.md
```

## How It Works

1. **Project Detection**: Walks git tree to discover `package.json`, `Cargo.toml`, `pyproject.toml`, `pubspec.yaml` files
2. **Change Tracking**: Uses git diff to detect changed files, marking projects with modifications
3. **Changepack Logs**: Stores version bump intentions in `.changepacks/changepack_log_*.json` with notes and timestamps
4. **Version Updates**: Reads changepack logs, calculates new versions (semver), updates files while preserving formatting
5. **Dependency Resolution**: Topologically sorts projects by dependencies for correct publish order
6. **Publishing**: Executes language-specific or custom publish commands in dependency order

### Changepack Log Format

```json
{
  "changes": {
    "packages/foo/package.json": "Minor",
    "crates/bar/Cargo.toml": "Patch"
  },
  "note": "Add new feature X and fix bug Y",
  "date": "2025-12-19T10:27:00.000Z"
}
```

## Development

### Build Workspace

```bash
cargo build
```

### Run Tests

```bash
cargo test
```

### Lint Check

```bash
cargo clippy
```

### Run Examples

Test with example projects:

```bash
cd examples/node/common
changepacks check
```

## Architecture

The project follows a trait-based, modular architecture:

- **Core** (`crates/core`) - Defines common traits (`Package`, `Workspace`, `ProjectFinder`) and types
- **Language Crates** (`crates/{node,python,rust,dart}`) - Implement language-specific project detection and version management
- **CLI** (`crates/cli`) - Command-line interface with clap, colored output, and interactive prompts
- **Utils** (`crates/utils`) - Shared utilities: git operations, version calculation, dependency sorting, config management
- **Bridges** (`bridge/{node,python}`) - N-API and PyO3 bindings for package manager distribution

### Key Design Patterns

- **Async-First**: All I/O operations use tokio for parallel execution
- **Format Preservation**: Language-specific parsers (toml_edit, yamlpatch, serde_json) maintain file formatting
- **Git-Native**: Uses git2 library for change detection and repository operations
- **Topological Sorting**: Kahn's algorithm ensures correct publish order based on dependencies

## Contributing

1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

## Sponsors

We're grateful to our sponsors for supporting changepacks development! If you're interested in sponsoring this project, please get in touch.

<div align="center">

<!-- Add your sponsors here -->
<!-- 
<a href="https://example.com">
  <img src="https://example.com/logo.png" width="150" alt="Sponsor Name" />
  <p><strong>Sponsor Name</strong></p>
</a>

<a href="https://example.com">
  <img src="https://example.com/logo2.png" width="150" alt="Another Sponsor" />
  <p><strong>Another Sponsor</strong></p>
</a>
-->

</div>

## Used By

The following open-source projects and companies are using changepacks:

<div align="center">

<a href="https://devup-ui.com">
  <img src="https://raw.githubusercontent.com/dev-five-git/devup-ui/main/media/logo.svg" width="150" alt="Devup UI" />
  <p><strong>Devup UI</strong></p>
</a>
<a href="https://braillify.kr">
  <img src="https://raw.githubusercontent.com/dev-five-git/braillify/main/media/logo.svg" width="150" alt="Braillify" />
  <p><strong>Braillify</strong></p>
</a>
<a href="https://devfive.kr">
  <img src="https://avatars.githubusercontent.com/u/85065616?s=200&v=4" width="150" alt="Braillify" />
  <p><strong>Devfive</strong></p>
</a>

<!-- Add your projects here -->
<!-- 
<a href="https://github.com/user/project">
  <img src="https://example.com/logo.png" width="150" alt="Project Name" />
  <p><strong>Project Name</strong></p>
</a>

<a href="https://example.com">
  <img src="https://example.com/company-logo.png" width="150" alt="Company Name" />
  <p><strong>Company Name</strong></p>
</a>
-->

</div>

If you're using changepacks in your project, we'd love to feature you here! Please open a [Pull Request](https://github.com/changepacks/changepacks/pulls) to add your project or company.

## License

This project is distributed under the MIT License. See the [LICENSE](LICENSE) file for more details.

## Roadmap

- [x] Node.js package management support
- [x] Python package management support
- [x] Rust package management support
- [x] Dart package management support
- [x] CI/CD integration support (JSON output, dry-run mode)
- [x] Dependency-aware publishing with topological sorting
- [x] Format preservation across all languages
- [x] Interactive CLI with tree view and colored output
- [x] Cross-platform distribution (Windows, macOS, Linux)
- [x] N-API and PyO3 bindings for npm/PyPI
- [ ] Plugin system for additional languages
- [ ] CHANGELOG.md generation from changepack logs
- [ ] GitHub Actions integration
- [ ] Pre-release version support

## Support

If you encounter any issues or have feature requests, please let us know on the [Issues](https://github.com/changepacks/changepacks/issues) page.

## Inspirations

- [changesets]https://github.com/changesets/changesets - Version management for JavaScript projects