Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

CLI `play --uri <album/playlist/artist/show> --queue` replaces playback instead of queueing

オープン 初心者向け
#827 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
2/5
見積もり時間
1〜3時間
初心者へのやさしさ
85/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
rust
領域
cli

調査の方向性

parse_spotify_uri の近くにある src/cli/clap.rs から始め、小さな純粋ヘルパー check_play_uri_flags を追加してください。このヘルパーは、トラック以外の URI に対する --queue と、プレイリスト以外の URI に対する --random を拒否します。src/cli/handle.rs の "play" アームにある --uri 分岐で、cli.play_uri(...) の前にこれを呼び出し、エラーは ? で伝播させてください。clap.rs の mod tests ブロックに play_uri_flags_* という名前のテストを追加します。cargo test --no-default-features --features telemetry,tui play_uri_flags で新しいテストが実行され、それらが合格し、不正な組み合わせが再生を開始せずにゼロ以外の終了コードで終了すれば完了です。

索引モデルが issue の本文から書いたものです。

説明

bug good first issue

What

spotatui play --uri accepts --queue and --random with every URI kind, but each flag only works with one kind. With any other kind the flag is silently ignored.

How to reproduce:

  1. Start something playing.
  2. Run spotatui play --uri spotify:album:<id> --queue. Swapping in a playlist, artist or show URI gives the same result.
  3. The album starts right away and replaces what was playing. Nothing gets queued.
  4. Run spotatui play --uri spotify:album:<id> --random. The album plays from the first track, with no warning.

The help already says what should happen: --queue "Adds track to queue instead of playing it directly", and --random "Plays a random track (only works with playlists)". So we want:

  • --queue with a URI that isn't a spotify:track: URI fails with a clear error and a non-zero exit code.
  • --random with a URI that isn't a spotify:playlist: URI does the same.
  • Neither case should start or change playback.

The cause: clap only blocks these combinations for the play --name NAME path, through conflicts_with_all on the --album/--artist/--playlist/--show/--track flags. A --uri only shows its kind inside the string, so clap can't catch it. play_uri then reads queue in the track branch only and random for playlists only.

Where to look

  • src/cli/clap.rs, lines 244-261: the queue and random args. Their conflicts only cover the --name category flags, never uri:
    Arg::new("queue")
      ...
      // Only works with tracks
      .conflicts_with_all(["album", "artist", "playlist", "show"])
      .help("Adds track to queue instead of playing it directly"),
    
    Arg::new("random")
      ...
      // Only works with playlists
      .conflicts_with_all(["track", "album", "artist", "show"])
      .help("Plays a random track (only works with playlists)"),
    
  • src/cli/clap.rs, lines 228-235: the uri arg uses .value_parser(parse_spotify_uri).
  • src/cli/clap.rs, lines 25-44: fn parse_spotify_uri(uri: &str) -> Result<String, String>. It already guarantees that a URI reaching the handler starts with one of spotify:track:, spotify:album:, spotify:artist:, spotify:playlist: or spotify:show: (the PLAYABLE list, checked with starts_with). Your new helper goes right next to it.
  • src/cli/clap.rs, lines 435-480: the mod tests block. It holds play_uri_accepts_the_spotify_kinds_it_can_start (440), play_uri_refuses_another_source_and_names_its_scheme (456) and play_uri_refuses_a_spotify_kind_it_cannot_start (469). Your tests go here.
  • src/cli/handle.rs, lines 141-154: the "play" arm of handle_matches:
    let queue = matches.get_flag("queue");
    let random = matches.get_flag("random");
    ...
    if let Some(uri) = matches.get_one::<String>("uri") {
      cli.play_uri(uri.to_string(), queue, random).await;
    } else if let Some(name) = matches.get_one::<String>("name") {
    
    handle_matches (line 53) returns Result<String>, so an Err here makes the CLI exit non-zero. anyhow and anyhow! are already imported at line 9.
  • src/cli/cli_app.rs, lines 434-520: pub async fn play_uri(&mut self, uri: String, queue: bool, random: bool).
    • Random is honored only under if uri.contains("spotify:playlist:") (line 437). Every other URI gets None (lines 489-491).
    • queue is read only in the track branch (lines 497-508): if queue { ... IoEvent::AddItemToQueue(uri) } else { ... }.
    • The context branch (lines 509-519) always sends IoEvent::StartPlayback(Some(uri), None, offset), whatever queue says. That's the bug.
  • src/cli/cli_app.rs, lines 523-539: CliApp::play (the --name path) also calls self.play_uri(uri, queue, random) at line 536. Clap already guards that path.

Possible solution

  • Add a small pure helper in src/cli/clap.rs, next to parse_spotify_uri:
    /// Refuses a `--queue` or `--random` that the `--uri` kind cannot honor.
    pub(super) fn check_play_uri_flags(uri: &str, queue: bool, random: bool) -> Result<(), String> {
      if queue && !uri.starts_with("spotify:track:") {
        return Err("--queue works only with a spotify:track: URI".to_string());
      }
      if random && !uri.starts_with("spotify:playlist:") {
        return Err("--random works only with a spotify:playlist: URI".to_string());
      }
      Ok(())
    }
    
    • It must be at least pub(super). mod clap; is private in src/cli/mod.rs, and parse_spotify_uri is a private fn, so handle.rs reaches the helper as super::clap::check_play_uri_flags.
    • Use starts_with, not contains, to match parse_spotify_uri.
    • Result<(), String> matches the style already in clap.rs. Returning anyhow::Result<()> is fine too, if you prefer it.
  • Call it in src/cli/handle.rs, inside the --uri branch and before cli.play_uri(...), so nothing reaches Spotify when the flags don't fit:
    if let Some(uri) = matches.get_one::<String>("uri") {
      super::clap::check_play_uri_flags(uri, queue, random).map_err(|e| anyhow!(e))?;
      cli.play_uri(uri.to_string(), queue, random).await;
    }
    
    You can also add clap::check_play_uri_flags to the use super::{...} block at the top of handle.rs (lines 4-7) and call it by its short name.
  • Traps and things to leave alone:
    • Don't put the check inside play_uri. The --name path (CliApp::play, line 536) also goes through it, and clap already guards that path.
    • Don't change play_uri's signature. It returns () and reports its own errors through handle_error.
    • No println! or eprintln! for the message. src/cli/AGENTS.md says stdout is for command output only. Return the error and let the caller report it.
    • --uri spotify:track:X --queue and --uri spotify:playlist:X --random must keep working exactly as they do now.
    • Leave the "Development Mode" comment at cli_app.rs lines 452-453 alone. It's out of scope for this issue.
    • Queueing a whole album could be a nice feature later. This issue only turns the unsupported combination into an error.
  • Tests to add, in the mod tests block of src/cli/clap.rs (line 436). They call the pure helper directly, so they don't need a Spotify account, a network or an audio device. Make every test name contain play_uri_flags so the filter below picks them up:
    • play_uri_flags_refuse_queue_with_an_album_uri: check_play_uri_flags("spotify:album:1", true, false) is Err, and the message contains --queue. Loop over album, artist, playlist and show if you like.
    • play_uri_flags_refuse_random_with_a_non_playlist_uri: ("spotify:artist:1", false, true) and ("spotify:track:1", false, true) are Err, and the message contains --random.
    • play_uri_flags_allow_queue_with_a_track_uri: ("spotify:track:1", true, false) is Ok(()).
    • play_uri_flags_allow_random_with_a_playlist_uri: ("spotify:playlist:1", false, true) is Ok(()).
    • play_uri_flags_allow_any_kind_without_flags: every kind with (false, false) is Ok(()).
  • CI runs clippy on the bin target only, so run cargo test to compile test code.
  • Leave tools/gates.count alone, new tests need no counter change.

Done when

  • cargo test --no-default-features --features telemetry,tui play_uri_flags runs your new tests and they pass. A filter that matches nothing still exits 0, so check the count.
  • Manual check (needs a Spotify login, so this one is optional): spotatui play --uri spotify:album:<id> --queue prints the --queue error, exits non-zero and leaves playback alone. spotatui play --uri spotify:track:<id> --queue still queues the track.
  • cargo fmt --all -- --check, cargo clippy --no-default-features --features telemetry,tui -- -D warnings and cargo test --no-default-features --features telemetry,tui pass.
主要言語
Rust
スター
1.4k
フォーク
238
平均マージ
8時間 56分
マージ済み PR(30日)
208

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

LargeModGames/spotatui のほかの issue

LargeModGames/spotatui の issue をすべて見る

似ている issue

Rust の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。