# How the Dry-Run Mode Simulates Downloads Without Saving Files in Spotify Saver

> Explore Spotify Saver's dry run mode to simulate downloads and preview tracks without network requests or saving files. Understand how this feature works for a safe preview experience.

- Repository: [Gabriel Baute/spotify-saver](https://github.com/gabrielbaute/spotify-saver)
- Tags: internals
- Published: 2026-03-02

---

**Dry-run mode lets you preview which YouTube Music videos would be downloaded for your Spotify tracks without making any network requests for audio or writing files to disk.**

The `gabrielbaute/spotify-saver` repository implements a `--dry-run` CLI flag that executes the full matching workflow while bypassing actual file operations. This feature helps you verify match quality between Spotify tracks and YouTube Music candidates before consuming bandwidth or storage space. Understanding how the dry-run mode works allows you to validate your entire playlist or album selections safely.

## How the Dry-Run Bypasses Actual Downloads

The dry-run mechanism intercepts the download workflow at the processor level, replacing file I/O operations with lightweight scoring and reporting logic.

### CLI Flag Detection

In [`spotifysaver/cli/commands/download/download.py`](https://github.com/gabrielbaute/spotify-saver/blob/main/spotifysaver/cli/commands/download/download.py), the `--dry-run` boolean option is defined at lines 31-33 and forwarded to entity processors at lines 71-78. When users append this flag to their command, it propagates through the `process_track`, `process_playlist`, and `process_album` functions without triggering the downloader initialization.

### Processor-Level Simulation

Each processor checks the `dry_run` parameter early in its execution path to conditionally skip downloads:

- **[`track.py`](https://github.com/gabrielbaute/spotify-saver/blob/main/track.py)** (lines 67-76): Handles single track preview logic
- **[`playlist.py`](https://github.com/gabrielbaute/spotify-saver/blob/main/playlist.py)** (lines 43-55): Iterates through playlist tracks for batch simulation
- **[`album.py`](https://github.com/gabrielbaute/spotify-saver/blob/main/album.py)** (lines 75-89): Processes album tracks with the same scoring logic

When the flag is enabled, these modules instantiate the `ScoreMatchCalculator` to evaluate the best YouTube candidate but deliberately avoid calling `YouTubeDownloaderForCLI.download_track_cli` or equivalent methods.

### Match Scoring and Reporting

The dry-run mode performs full candidate evaluation—calculating match scores based on title, artist, and duration similarity—then outputs the selected video's metadata to the terminal. The system displays the candidate title, YouTube video ID, and total score using colored prompts (prefixed with 🧪), allowing you to verify match quality before committing to actual downloads.

## Using Dry-Run Mode to Preview Downloads

You can simulate downloads for individual tracks, entire playlists, or full albums without creating files.

### Previewing a Single Track

Run the download command with the `--dry-run` flag for a specific Spotify track URL:

```bash
spotifysaver download "https://open.spotify.com/track/5K4W6rqBFWDnAN6FQUkS6x" --dry-run

```

The output shows the selected YouTube candidate and match score without downloading:

```

🧪 Dry run for track: Bad Guy
  → Selected candidate: Billie Eilish - Bad Guy (Official Video)
    Video ID: dQw4w9WgXcQ
    Total score: 95 (passed: True)

```

*Implemented in [`track.py`](https://github.com/gabrielbaute/spotify-saver/blob/main/track.py) where the `dry_run` parameter triggers the score-explanation block at lines 67-76.*

### Validating an Entire Playlist

For playlists, the mode iterates through each track and reports individual match scores:

```bash
spotifysaver download "https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M" --dry-run

```

Result excerpt:

```

🧪 Dry run for playlist: Today's Top Hits
🎵 Track: Blinding Lights
  → Selected candidate: The Weeknd - Blinding Lights (Official Video)
    Video ID: 4NRXx6U8ABQ
    Total score: 98 (passed: True)
...

```

*This logic resides in [`playlist.py`](https://github.com/gabrielbaute/spotify-saver/blob/main/playlist.py) at lines 43-55, where the dry-run loop processes `playlist.tracks` without invoking the downloader.*

### Checking a Full Album

Album dry-runs follow the same pattern, evaluating every track in the album's tracklist:

```bash
spotifysaver download "https://open.spotify.com/album/1ATL5GLyefJaxhQzSPVrLX" --dry-run

```

Output format:

```

🧪 Dry run for album: Thriller
🎵 Track: Thriller
  → Selected candidate: Michael Jackson - Thriller (Official Video)
    Video ID: sOnqjkJTMaA
    Total score: 99 (passed: True)
...

```

*Found in [`album.py`](https://github.com/gabrielbaute/spotify-saver/blob/main/album.py) at lines 75-89, where the dry-run block iterates over `album.tracks`.*

## Summary

- **Dry-run mode** uses the `--dry-run` CLI flag defined in [`download.py`](https://github.com/gabrielbaute/spotify-saver/blob/main/download.py) (lines 31-33) to disable actual file operations
- Entity processors in [`track.py`](https://github.com/gabrielbaute/spotify-saver/blob/main/track.py), [`playlist.py`](https://github.com/gabrielbaute/spotify-saver/blob/main/playlist.py), and [`album.py`](https://github.com/gabrielbaute/spotify-saver/blob/main/album.py) detect the flag and bypass `YouTubeDownloaderForCLI` invocation
- The `ScoreMatchCalculator` executes normally to show which YouTube video would be selected for each Spotify entity
- No audio download requests or file system writes occur during simulation
- Terminal output displays video IDs, titles, and numerical match scores using colored formatting

## Frequently Asked Questions

### Does dry-run mode use internet bandwidth?

Dry-run mode performs metadata lookups to identify YouTube candidates but does not download audio streams or cover art, resulting in minimal bandwidth usage compared to actual downloads.

### Can I see the match quality scores in dry-run mode?

Yes, the terminal output displays the total match score and pass/fail status calculated by `ScoreMatchCalculator` for each track, allowing you to verify selection accuracy.

### Is the dry-run output format consistent across tracks, albums, and playlists?

Each entity type follows a similar reporting pattern but includes context-specific headers—displaying track names for single downloads, album names for album processing, and playlist names for playlist iterations.

### Where is the dry-run execution logic implemented?

According to the source code, the flag definition resides in [`spotifysaver/cli/commands/download/download.py`](https://github.com/gabrielbaute/spotify-saver/blob/main/spotifysaver/cli/commands/download/download.py) at lines 31-33, while the execution bypass logic is implemented in [`track.py`](https://github.com/gabrielbaute/spotify-saver/blob/main/track.py) (lines 67-76), [`playlist.py`](https://github.com/gabrielbaute/spotify-saver/blob/main/playlist.py) (lines 43-55), and [`album.py`](https://github.com/gabrielbaute/spotify-saver/blob/main/album.py) (lines 75-89) respectively.