Place slides under public/ and tell them apart from articles by marp: true - #423
Merged
Merged
Conversation
… true Slides now live in the same public/ directory as articles, with public/slides/ as the default location for new and pulled slides. A file is treated as a slide when its frontmatter has `marp: true`, so it can be placed anywhere under public/. Both repositories share public/.remote/ as the mirror. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The slide repository now shares public/ with the article repository, so preview watches it once, and one file can no longer be both an article and a slide. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Items and slides now share public/, so checking the target basename through loadItemByBasename / loadSlideByBasename missed files of the other kind and overwrote them with an empty template. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Member
Author
|
AI Review の指摘に対応しました(a4b9c05)。
|
tomoasleep
commented
Sep 25, 2026
tomoasleep
left a comment
Member
Author
There was a problem hiding this comment.
🤖 AI Review 🤖
問題はありません。
その他確認した項目
何を確認したか
- PR: #423
- diff: main...move-slide-directory
- CI state: success(6/6: check_test_execution_conditions, lint, test x3, build)
- 既存レビュー: 行コメント 0 件(unresolved なし)、general comment 1 件(tomoasleep 本人、commit a4b9c05 で対応済み)
見たが問題にしなかった観点
- general comment にある
createItem/createSlideの存在チェック変更は commit a4b9c05 で実装済みと確認した。file-system-repo.ts/slide-file-system-repo.tsの該当箇所は、種別で絞り込むloadItemByBasename/loadSlideByBasenameではなくpublic/配下のファイル名一覧(getItemFilenames/getSlideFilenames)と照合するよう変わっており、反対の種別の basename を指定すると'<basename>.md' is already existに到達することをテストとコードの両方で確認した。 - 同コメントにある「
marp: trueによる記事の除外はフラグに関係なく常に効く」という記述も、FileSystemRepo#getItemDataのisSlideMarkdownチェックがexperimentalSlideFeatureEnabledを見ずに常に適用される実装と一致しており、PR description もこの挙動に合わせて修正済みであることを確認した。 publish.tsから「記事とスライドの両方に同じ basename がある」エラー分岐を削除した点も、両 repo が同一ファイルをmarp: trueで排他的に判定するようになったため到達し得なくなった分岐であり、対応するテストも削除されていて妥当と判断した。SlideFileContent.fromSlideは Qiita 側の markdown にmarpキーが無くてもオブジェクトスプレッドでmarp: trueを付与する実装になっており、ミラーとの差分判定を崩すような roundtrip の不整合はない。.remoteミラーが記事・スライドで共有ディレクトリになった点も、getItemData/getSlideDataがそれぞれisSlideMarkdownで読み分けるため実害はない。
tomoasleep に確認するべき点
ディレクトリ付き basename で作成したとき、記事だけ title にディレクトリ名が残る
qiita new --slide slides/newSlide001 は title を path.basename した newSlide001 にする一方、qiita new talks/article は basename をそのまま title に使うため talks/article が title に残る。PR description にはスライド側でこの変更をした理由は書かれているが、記事側を揃えなかった理由には触れていない。意図した非対称であれば問題ないが、単なる対応漏れであれば記事側も揃える余地がある。記事でディレクトリ付き basename を使うケース自体が今回のスコープの中心ではないため、ブロッキングではない。
補足
CI は全 6 チェックが成功しており、conflict もない(mergeable: MERGEABLE)。ただし本 PR にはまだ人間の承認レビューが付いておらず(reviewDecision: REVIEW_REQUIRED、reviewRequests は空)、このリポジトリの branch protection は承認レビューを必須としている。
head: a4b9c05
Member
Author
|
#421 の上の stacked PR にしてほしい |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
スライドの置き場所をルート直下の
slides/からpublic/配下に移し、public/内の記事とスライドを frontmatter の内容で判別するようにする。marp: trueがあるファイルをスライド、それ以外を記事として扱う。スライドはpublic/配下のどこに置いてもよいqiita new --slideのデフォルト作成先と、qiita pullでローカルに無いスライドを書き出す先をpublic/slides/にする。basename を明示すればそのパスに作成する(例:qiita new --slide talks/deck→public/talks/deck.md).remoteミラーは記事・スライドともpublic/.remote/を共有するqiita new --slideで作るファイルの title は、basename からディレクトリを除いた部分にする(slides/newSlide001ではなくnewSlide001)スライドの作成・pull・publish・preview は、これまでどおり
experimentalSlideFeatureEnabledが有効なときだけ動く。一方、marp: trueのファイルを記事の一覧・publish 対象から外す判定はフラグに関係なく常に効く。フラグを無効にしたあとに、スライドのファイルが記事として投稿されないようにするため。動作確認
yarn lint/yarn build/yarn test(24 suites, 222 tests)がいずれも成功。追加・更新した主なテスト:
src/lib/file-system-repo.test.ts:public/直下・public/slides/配下のスライドが記事の一覧・basename 指定・id 指定のいずれにも出ないこと / 既存のスライドと同じ basename でqiita newしてもスライドを上書きしないことsrc/lib/slide-file-system-repo.test.ts:public/直下・配下のスライドが一覧に出て、記事は出ないこと /qiita new --slideのデフォルト作成先がpublic/slides/newSlide001.mdになること / pull でローカルに無いスライドがpublic/slides/<uuid>.mdに書き出されること /slides/以外の場所にあるスライドがその場所のまま更新されること /marpの無い markdown を取得したときにmarp: trueが付くこと / 既存の記事と同じ basename でqiita new --slideしても記事を上書きしないことsrc/lib/get-slide-file-system-repo.test.ts: ルートがpublic/になりpublic/slides/が作られることsrc/commands/preview.test.ts: 監視対象がpublic/の 1 つだけになることビルド済み CLI(
node dist/main.js)で、experimental フラグを有効にした空のディレクトリに対して以下を確認した。qiita new --slidepublic/slides/newSlide001.mdがmarp: true付きで作成されるqiita new --slide talks/deck(public/talks/作成済み)public/talks/deck.mdが作成されるqiita new articlepublic/article.mdが作成されるqiita publish/pull/previewは Qiita API との通信が必要なため、上記の自動テストでの確認のみ。How
判別はディレクトリではなく内容で行う
FileSystemRepo#getItemData/SlideFileSystemRepo#getSlideDataがファイルを読んだ直後にisSlideMarkdown(marp: trueの厳密比較)で振り分ける。一覧・basename 指定・id 指定の読み込みはすべてここを通るので、記事の一覧にスライドが、スライドの一覧に記事が混ざらない。一覧取得(
readdir)の段階では振り分けない。ファイル名だけでは判別できず、そこで全ファイルを読むと basename 解決のたびに読み込みが増えるため。Qiita から取得したスライドには
marp: trueを必ず付けるQiita 上で書かれたスライドの markdown に
marp: trueが無いと、pull したファイルが次回から記事として扱われ、qiita publish --allで記事として投稿されてしまう。SlideFileContent.fromSlideでミラー・ローカルともmarp: trueを付与する。既にmarpキーがある場合はキーの位置を保つので、ミラーとの差分判定には影響しない。新規作成時の存在チェックはファイル名で行う
記事とスライドが同じ
public/を共有するので、qiita new/qiita new --slideで指定した basename のファイルが反対の種別で既にあることがある。createItem/createSlideの存在チェックを、種別で絞り込むloadItemByBasename/loadSlideByBasenameではなく、public/配下のファイル名一覧で行う。これで既存のファイルを空のテンプレートで上書きせず、'<basename>.md' is already existのエラーになる。preview / publish の後始末
qiita previewの監視対象はpublic/だけになる(スライドのルートもpublic/なので重複して登録しない)qiita publish <basename>の「記事とスライドの両方に同じ basename がある」エラーは、1 ファイルがどちらか一方にしか判別されないため到達しなくなったので削除したGitHub Actions の
actions/publish/action.ymlはgit add ${{ inputs.root }}/public/*でpublic/配下を再帰的にステージするので変更していない。Why
public/とslides/を並列に置くと、何を意味するディレクトリなのか分かりにくく、ユーザーがファイルを置く場所も別々に縛られる。スライドをpublic/の中に入れ、場所ではなく内容で判別すれば、public/slides/はデフォルトの置き場所に留まり、記事とスライドを好きなディレクトリ構成で管理できる。移行について
実験的機能のため、既存の
slides/配下のファイルは自動で移行しない。投稿済みのスライドは次回のqiita pullでpublic/slides/に取得し直される。未投稿のローカルのみのスライドはpublic/配下へ手動で移動する必要がある。Refs
既存の挙動(この PR のスコープ外)
qiita new --slide talks/deckは、public/talks/が存在しないと書き込みに失敗する。記事のqiita new talks/articleも同じ挙動なので、この PR では揃えたままにしている。🤖 Generated with Claude Code