audiobook-forge 2.4.2

CLI tool for converting audiobook directories to M4B format with chapters and metadata
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
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
# Contributing to Audiobook Forge ๐ŸŽง

First off, thank you for considering contributing to Audiobook Forge! It's people like you that make this tool better for everyone.

## ๐Ÿ“‹ Table of Contents

- [Code of Conduct]#code-of-conduct
- [Getting Started]#getting-started
- [Development Setup]#development-setup
- [How to Contribute]#how-to-contribute
- [Code Style Guidelines]#code-style-guidelines
- [Testing]#testing
- [Commit Messages]#commit-messages
- [Pull Request Process]#pull-request-process
- [Reporting Bugs]#reporting-bugs
- [Suggesting Features]#suggesting-features

---

## ๐Ÿ“œ Code of Conduct

This project and everyone participating in it is governed by our Code of Conduct. By participating, you are expected to uphold this code. Please report unacceptable behavior to the project maintainers.

### Our Standards

- **Be respectful** and inclusive
- **Be collaborative** and constructive
- **Focus on what is best** for the community
- **Show empathy** towards other community members

---

## ๐Ÿš€ Getting Started

### Prerequisites

Before contributing, make sure you have:

- **Rust 1.75+** installed ([rustup.rs]https://rustup.rs/)
- **Git** for version control
- **FFmpeg, AtomicParsley, and MP4Box** installed
- Familiarity with Rust and async programming (Tokio)

### Quick Setup

```bash
# Fork and clone the repository
git clone https://github.com/YOUR_USERNAME/audiobook-forge
cd audiobook-forge

# Build the project
cargo build

# Run tests
cargo test

# Run the binary
cargo run -- check
```

---

## ๐Ÿ› ๏ธ Development Setup

### 1. Fork the Repository

Click the "Fork" button at the top of the repository page.

### 2. Clone Your Fork

```bash
git clone https://github.com/YOUR_USERNAME/audiobook-forge
cd audiobook-forge
```

### 3. Add Upstream Remote

```bash
git remote add upstream https://github.com/juanra/audiobook-forge
git fetch upstream
```

### 4. Create a Branch

```bash
git checkout -b feature/my-awesome-feature
```

### 5. Install Development Tools

```bash
# Install rustfmt (code formatter)
rustup component add rustfmt

# Install clippy (linter)
rustup component add clippy

# Install cargo-watch (optional, for auto-rebuild)
cargo install cargo-watch
```

### 6. Build and Test

```bash
# Build
cargo build

# Run tests
cargo test

# Run clippy
cargo clippy -- -D warnings

# Format code
cargo fmt
```

---

## ๐Ÿค How to Contribute

### Types of Contributions

We welcome various types of contributions:

1. **Bug fixes** - Fix issues in the codebase
2. **New features** - Add new functionality
3. **Documentation** - Improve README, docs, or code comments
4. **Tests** - Add or improve test coverage
5. **Performance** - Optimize existing code
6. **Refactoring** - Improve code quality without changing behavior

### Contribution Workflow

1. **Find or create an issue** - Check if an issue exists, or create one
2. **Discuss the approach** - Comment on the issue to discuss your plan
3. **Fork and branch** - Create a feature branch from `master`
4. **Implement changes** - Write code following our style guide
5. **Add tests** - Ensure new code is tested
6. **Run checks** - Format, lint, and test your code
7. **Commit** - Use conventional commit messages
8. **Push and PR** - Open a pull request with a clear description

---

## ๐ŸŽจ Code Style Guidelines

### Rust Style

Follow the official [Rust Style Guide](https://doc.rust-lang.org/1.0.0/style/):

- Use `rustfmt` for formatting (run `cargo fmt` before committing)
- Use `clippy` for linting (run `cargo clippy`)
- Follow Rust naming conventions:
  - `snake_case` for functions, variables, modules
  - `PascalCase` for types, traits, enums
  - `SCREAMING_SNAKE_CASE` for constants

### Code Organization

```rust
// Order of items in a module:
// 1. Imports
// 2. Type definitions
// 3. Constants
// 4. Public functions
// 5. Private functions
// 6. Tests

use std::path::Path;
use anyhow::Result;

pub struct MyType {
    field: String,
}

const MAX_SIZE: usize = 1024;

pub fn public_function() -> Result<()> {
    // Implementation
    Ok(())
}

fn private_helper() {
    // Implementation
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_something() {
        // Test implementation
    }
}
```

### Error Handling

- Use `anyhow::Result<T>` for application errors
- Use `thiserror` for custom error types
- Add context to errors with `.context()`

```rust
use anyhow::{Context, Result};

fn process_file(path: &Path) -> Result<()> {
    let content = std::fs::read_to_string(path)
        .context(format!("Failed to read file: {}", path.display()))?;

    // Process content...

    Ok(())
}
```

### Documentation

- Add doc comments to public APIs
- Use `///` for item documentation
- Use `//!` for module documentation
- Include examples in doc comments when helpful

```rust
/// Processes an audiobook directory and converts it to M4B format.
///
/// # Arguments
///
/// * `path` - Path to the audiobook directory
/// * `config` - Configuration options for processing
///
/// # Returns
///
/// Returns `Ok(ProcessingResult)` on success, or an error if processing fails.
///
/// # Example
///
/// ```no_run
/// let result = process_audiobook(Path::new("/path/to/book"), &config)?;
/// println!("Processed: {}", result.output_path.display());
/// ```
pub fn process_audiobook(path: &Path, config: &Config) -> Result<ProcessingResult> {
    // Implementation
}
```

### Async/Await

- Use `async/await` for I/O operations
- Use `tokio::spawn` for parallel tasks
- Use semaphores for resource limiting

```rust
use tokio::sync::Semaphore;
use std::sync::Arc;

async fn process_parallel(books: Vec<Book>, max_parallel: usize) -> Result<()> {
    let semaphore = Arc::new(Semaphore::new(max_parallel));

    let mut handles = vec![];

    for book in books {
        let permit = semaphore.clone().acquire_owned().await?;

        let handle = tokio::spawn(async move {
            let result = process_book(book).await;
            drop(permit);
            result
        });

        handles.push(handle);
    }

    // Wait for all tasks
    for handle in handles {
        handle.await??;
    }

    Ok(())
}
```

---

## ๐Ÿงช Testing

### Running Tests

```bash
# Run all tests
cargo test

# Run specific test
cargo test test_name

# Run tests with output
cargo test -- --nocapture

# Run tests in a specific module
cargo test models::
```

### Writing Tests

- Add unit tests in the same file as the code (`#[cfg(test)] mod tests`)
- Add integration tests in `tests/` directory
- Use descriptive test names: `test_<what>_<condition>_<expected_result>`

```rust
#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_quality_profile_comparison_higher_bitrate_wins() {
        let q1 = QualityProfile {
            bitrate: 128000,
            sample_rate: 44100,
            channels: 2,
            codec: "mp3".to_string(),
            duration: 0.0,
        };

        let q2 = QualityProfile {
            bitrate: 192000,
            sample_rate: 44100,
            channels: 2,
            codec: "mp3".to_string(),
            duration: 0.0,
        };

        assert!(q2.is_better_than(&q1));
    }

    #[tokio::test]
    async fn test_async_function() {
        let result = async_function().await;
        assert!(result.is_ok());
    }
}
```

### Test Coverage

- All public functions should have tests
- Test both success and failure cases
- Test edge cases (empty input, invalid data, etc.)
- Use `tempfile` crate for temporary files/directories in tests

---

## ๐Ÿ“ Commit Messages

We follow [Conventional Commits](https://www.conventionalcommits.org/) specification:

### Format

```
<type>(<scope>): <description>

[optional body]

[optional footer]
```

### Types

- `feat`: New feature
- `fix`: Bug fix
- `docs`: Documentation changes
- `test`: Adding or updating tests
- `refactor`: Code refactoring (no behavior change)
- `perf`: Performance improvements
- `chore`: Build process, dependencies, etc.
- `style`: Code style changes (formatting, etc.)

### Examples

```bash
# Feature
git commit -m "feat(audio): add CUE file parsing support"

# Bug fix
git commit -m "fix(metadata): handle missing album tag gracefully"

# Documentation
git commit -m "docs(readme): update installation instructions"

# Breaking change
git commit -m "feat(config): change default parallel workers

BREAKING CHANGE: Default parallel workers changed from 4 to CPU cores / 2"
```

### Guidelines

- Use present tense ("add feature" not "added feature")
- Use imperative mood ("move cursor to..." not "moves cursor to...")
- Limit first line to 72 characters
- Reference issues: "fixes #123" or "closes #456"

---

## ๐Ÿ”„ Pull Request Process

### Before Submitting

1. **Update documentation** if you changed APIs
2. **Add tests** for new functionality
3. **Run all checks**:
   ```bash
   cargo fmt
   cargo clippy -- -D warnings
   cargo test
   cargo build --release
   ```
4. **Update CHANGELOG.md** if applicable

### PR Description Template

```markdown
## Description
Brief description of what this PR does.

## Motivation
Why is this change needed?

## Changes
- Change 1
- Change 2
- Change 3

## Testing
How was this tested?

## Screenshots (if applicable)
Add screenshots or output examples

## Checklist
- [ ] Code follows style guidelines
- [ ] Self-review completed
- [ ] Comments added for complex code
- [ ] Documentation updated
- [ ] Tests added/updated
- [ ] All tests passing
- [ ] No new warnings from clippy
- [ ] CHANGELOG.md updated (if applicable)

## Related Issues
Fixes #123
Closes #456
```

### Review Process

1. **Automated checks** must pass (CI/CD)
2. **Code review** by at least one maintainer
3. **Changes requested** - address feedback and push updates
4. **Approval** - maintainer approves PR
5. **Merge** - maintainer merges into master

### After Merge

- Delete your feature branch
- Pull latest changes from upstream
- Continue with next contribution!

---

## ๐Ÿ› Reporting Bugs

### Before Reporting

1. **Check existing issues** - your bug might already be reported
2. **Try latest version** - bug might already be fixed
3. **Check dependencies** - run `audiobook-forge check`

### Bug Report Template

When creating a bug report, include:

```markdown
**Describe the bug**
A clear description of what the bug is.

**To Reproduce**
Steps to reproduce:
1. Run command '...'
2. With these files '...'
3. See error

**Expected behavior**
What you expected to happen.

**Actual behavior**
What actually happened.

**Output/Logs**
```
Paste error output here (use --verbose for detailed logs)
```

**Environment**
- OS: [e.g., macOS 13.0, Ubuntu 22.04]
- Rust version: [output of `rustc --version`]
- audiobook-forge version: [output of `audiobook-forge --version`]
- FFmpeg version: [output of `ffmpeg -version`]

**Additional context**
Any other relevant information.
```

---

## ๐Ÿ’ก Suggesting Features

### Before Suggesting

1. **Check existing issues/discussions** - feature might already be proposed
2. **Consider scope** - does it fit the project's goals?
3. **Think about implementation** - is it technically feasible?

### Feature Request Template

```markdown
**Feature Description**
Clear description of the feature.

**Use Case**
What problem does this solve? Who benefits?

**Proposed Solution**
How could this be implemented?

**Alternatives Considered**
What other approaches did you consider?

**Additional Context**
Mockups, examples, references, etc.
```

---

## ๐Ÿ“š Additional Resources

### Documentation

- [Rust Book]https://doc.rust-lang.org/book/
- [Tokio Documentation]https://tokio.rs/tokio/tutorial
- [Clap Documentation]https://docs.rs/clap/
- [Project Documentation]docs/

### Getting Help

- **GitHub Discussions**: Ask questions, share ideas
- **GitHub Issues**: Report bugs, request features
- **Documentation**: Check `docs/` folder and `AGENTS.md`

---

## ๐ŸŽฏ Good First Issues

Looking for a place to start? Check out issues labeled:
- `good first issue` - Easy issues for newcomers
- `help wanted` - Issues where we need help
- `documentation` - Documentation improvements

---

## ๐Ÿ™ Recognition

Contributors will be recognized in:
- GitHub contributors page
- CHANGELOG.md for significant contributions
- Acknowledgments section in README.md

---

Thank you for contributing to Audiobook Forge! ๐ŸŽงโœจ