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

sana and scat: crashes, and records lost or doubled with exit 0

オープン
#617 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

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

評価

難易度
5/5
見積もり時間
1週間以上
初心者へのやさしさ
25/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
go

調査の方向性

The report covers sana and scat parsing, file discovery, process watching, and live streaming, but names no source files or tests. Start by locating both command entry points and the relevant tests, then trace the reported cases one at a time. Done means each expected behavior is fixed and covered, including errors, without losing or duplicating records.

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

説明

Version: seqkit v2.14.0 (bioconda), Linux x86_64

All examples below use small files made with printf. Each problem is a crash,
a lost record or a doubled record. In most cases the command exits 0.

Test files used in more than one section:

$ printf '@a\nACGT\n+\nIIII\n' > good.fq
$ mkdir t7 && cp good.fq t7/a.fq

sana: -i '' stops with a Go deadlock

What happens

Every other bad value of -i gives [CRIT] Invalid format specified. An empty
value gives a Go deadlock and a goroutine trace.

$ seqkit sana -i '' good.fq
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan send (nil chan)]:
...
$ echo $?
2
Expected

The same [CRIT] Invalid format specified message as for other bad values.

sana: a directory is read as an empty file (exit 0)

$ mkdir d
$ seqkit sana d
[INFO] File: d	Pass records: 0	Discarded lines: 0
$ echo $?
0
Expected

An error such as read d: is a directory and a non-zero exit code.

sana -i fasta: one bad line before the first header discards the whole file

What happens

A line such as junk or ;comment before the first header discards every
record of the file, good records included. FASTQ input drops only the bad line.
The line numbers in the messages are also wrong (-1, 0).

$ printf 'junk\n>a\nACGT\n>b\nGGCC\n' > junk.fa
$ seqkit sana -i fasta junk.fa
[INFO] File: junk.fa	Discarded line: line 1: expected header line, got: junk	-1:	 junk
[INFO] File: junk.fa	Discarded line: line 1: expected header line, got: junk	0:	 >a
[INFO] File: junk.fa	Discarded line: line 1: expected header line, got: junk	1:	 ACGT
[INFO] File: junk.fa	Discarded line: line 1: expected header line, got: junk	2:	 >b
[INFO] File: junk.fa	Pass records: 0	Discarded lines: 4
$ echo $?
0
Expected

Only junk is discarded. Records a and b pass.

sana -i fasta: a line > alone discards the record before it

What happens

A header line with an empty ID is read as a sequence line of the record before
it. That good record then fails. FASTQ accepts the same empty ID.

$ printf '>a\nACGT\n>\n>b\nGGCC\n' > gt.fa
$ seqkit sana -i fasta gt.fa
[INFO] File: gt.fa	Discarded line: line 3: invalid sequence line: >	-1:	 >a
[INFO] File: gt.fa	Discarded line: line 3: invalid sequence line: >	0:	 ACGT
[INFO] File: gt.fa	Discarded line: line 3: invalid sequence line: >	1:	 >
[INFO] File: gt.fa	Pass records: 1	Discarded lines: 3
>b
GGCC
Expected

Record a passes. The > line is a header with an empty ID.

sana -i fasta: a file with CRLF line ends loses every record (exit 0)

What happens

The CR is taken as a bad sequence letter. FASTQ input removes the CR.

$ printf '>a\r\nACGT\r\n>b\r\nGGCC\r\n' > crlf.fa
$ seqkit sana -i fasta crlf.fa
[INFO] File: crlf.fa	Discarded line: line 2: invalid sequence line: ACGT	-1:	 >a
[INFO] File: crlf.fa	Discarded line: line 2: invalid sequence line: ACGT	0:	 ACGT
[INFO] File: crlf.fa	Discarded line: line 4: invalid sequence line: GGCC	1:	 >b
[INFO] File: crlf.fa	Pass records: 0	Discarded lines: 3
$ echo $?
0
Expected

The CR at each line end is removed, as for FASTQ. Both records pass.

sana -i fasta: a failed last record is not fully reported

What happens

When the LAST record fails, the sequence lines after the bad line are not
listed and not counted. The same record in the middle of the file is listed
completely.

$ printf '>s1\nAC\nGT\n>s2\nGG\nG1G\nTT\n' > badlast.fa
$ seqkit sana -i fasta badlast.fa 2>&1 >/dev/null
[INFO] File: badlast.fa	Discarded line: line 6: invalid sequence line: G1G	2:	 >s2
[INFO] File: badlast.fa	Discarded line: line 6: invalid sequence line: G1G	3:	 GG
[INFO] File: badlast.fa	Discarded line: line 6: invalid sequence line: G1G	4:	 G1G
[INFO] File: badlast.fa	Pass records: 1	Discarded lines: 3

$ printf '>s1\nAC\nGT\n>s2\nGG\nG1G\nTT\n>s3\nAA\n' > badmid.fa
$ seqkit sana -i fasta badmid.fa 2>&1 >/dev/null
...	4:	 G1G
...	5:	 TT
[INFO] File: badmid.fa	Pass records: 2	Discarded lines: 4
Expected

TT is listed, and Discarded lines: 4, for the last record too.

scat -f: one dangling symlink stops the run, and no record comes out

$ mkdir t6 && printf '@a\nACGT\n+\nIIII\n' > t6/a.fastq && ln -s nowhere.fq t6/dangling.fq
$ seqkit scat -f --quiet t6
[ERRO] stat t6/dangling.fq: no such file or directory
$ echo $?
255

Record a is lost. With more files, some records come out or none, by chance.

Expected

An error for the bad link, and all other files are read.

scat -f: a file that cannot be read is skipped with no message (exit 0)

$ mkdir t2 && printf '@a\nACGT\n+\nIIII\n' > t2/a.fq && printf '@u\nACGT\n+\nIIII\n' > t2/u.fq && chmod 000 t2/u.fq
$ seqkit scat -f --quiet t2
@a
ACGT
+
IIII
$ echo $?
0
Expected

open t2/u.fq: permission denied and a non-zero exit code.

scat -i fasta: the same three FASTA problems as sana

A line before the first header, CRLF line ends and a last line > each lose
the good records of the file, with exit 0.

$ mkdir t3 && printf 'junk\n>a\nACGT\n' > t3/a.fa
$ seqkit scat -f --quiet -i fasta t3          # no record
$ mkdir t4 && printf '>a\r\nACGT\r\n' > t4/a.fa
$ seqkit scat -f --quiet -i fasta t4          # no record
$ mkdir t5 && printf '>a\nACGT\n>\n' > t5/a.fa
$ seqkit scat -f --quiet -i fasta t5          # no record
From file: t5/a.fa	Discarded line: line 3: invalid sequence line: >	-1:	 >a
From file: t5/a.fa	Discarded line: line 3: invalid sequence line: >	0:	 ACGT
Expected

Record a comes out in all three cases.

scat -p: works the wrong way round

What happens

The help says "after process with this PID exited". With the PID of a running
process of the same user, scat ends after about 0.5 s and says the process
exited. With a PID that does not exist, scat never ends.

$ seqkit scat -p $$ t7
[INFO] Running until process with PID 3212779 exits.
[INFO] Watched process with PID 3212779 exited.
...
$ kill -0 $$ && echo alive
alive

$ timeout 5 seqkit scat --quiet -p 999999 t7; echo $?
...
124
Expected

scat runs while the process exists, and ends when it no longer exists.

scat (live mode): renaming a watched file crashes

$ mkdir L4 && printf '@a\nACGT\n+\nIIII\n' > L4/n.fq
$ seqkit scat L4 &           # then, 2 s later:
$ mv L4/n.fq L4/m.fq
[INFO] Stopped watching renamed file: L4/n.fq
[CRIT] Invalid renaming feedback: 2

Exit code 1. In other runs the records of the renamed file come out a second
time instead.

Expected

No crash, and each record comes out once.

scat (live mode): a small append does not come out until Ctrl-C

What happens

The help says "real time ... streaming". With -d 0, one record appended to a
watched file does not come out. It comes out only when scat gets SIGINT.
A large append (about 66 KB) comes out within a few seconds.

$ mkdir L3 && printf '@a\nACGT\n+\nIIII\n' > L3/n.fq
$ seqkit scat -d 0 L3 > out.fq &      # then:
$ printf '@b\nGGCC\n+\nIIII\n' >> L3/n.fq
$ grep -c '^@' out.fq                 # 5 s later
1
                                      # after SIGINT: 2
Expected

The appended record comes out without waiting for the end.

scat: -X/--infile-list is ignored

$ printf 't7\n' > list.txt; mkdir t8
$ seqkit scat -f -X list.txt t8
...
[INFO] Streaming fastq records from directory: t8
[INFO] Total stats:	Pass records: 0	Discarded lines: 0
Expected

The folder t7 from the list is read, or an error says that -X is not
supported.

scat: the same folder twice, or a folder and its sub-folder, doubles records

$ seqkit scat -f --quiet t7 t7          # record a twice
$ mkdir -p t9/sub && printf '@s\nACGT\n+\nIIII\n' > t9/sub/s.fq
$ seqkit scat -f --quiet t9 t9/sub      # record s twice

Exit code 0 in both cases.

Expected

Each file is read once.

主要言語
Go
スター
1.6k
フォーク
189
PR マージ指標
30日以内にマージされた PR はありません

環境構築

  • Dockerfile または Docker Compose ファイルあり
  • プルリクエストのテンプレートなし
  • コントリビューションガイドなし

はじめの一歩

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

shenwei356/seqkit のほかの issue

shenwei356/seqkit の issue をすべて見る

似ている issue

Go の issue をもっと見る

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

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