Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .claude/rules/scratch-gui/smalruby-prettier-files.md
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ upstream (Scratch) ファイルは対象外。
- `test/unit/lib/ruby-roundtrip-puts-concat.test.js`
- `test/unit/lib/ruby-roundtrip-super.test.js`
- `test/unit/lib/ruby-screenshot.test.js`
- `test/unit/lib/smalruby-original-sprites.test.js`
- `test/unit/lib/smalrubot-firmware-flasher.test.js`
- `test/unit/lib/ruby-script-preview.test.js`
- `test/unit/lib/ruby-to-blocks-converter-version.test.js`
Expand Down
30 changes: 30 additions & 0 deletions .claude/skills/upstream-merge/phase2-conflicts.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,36 @@ upstream が追加した新しいファイルや、revert 対象外のファイ

---

### sprites.json / costumes.json (Smalruby 独自エントリ消失リスク)

**コンフリクトとして検出されないケースが多い** ため要注意。upstream の
`packages/scratch-gui/src/lib/libraries/sprites.json` /
`packages/scratch-gui/src/lib/libraries/costumes.json` が更新されると、
git の auto-merge が成功してしまい、**Smalruby 独自エントリ (Shimaraby,
Shimacat) が静かに消失する** ことがある (issue #688 で発生)。

**マージ後に必ず実行する確認**:

```bash
# Shimaraby / Shimacat が残っていることを確認
docker compose run --rm app bash -c "cd packages/scratch-gui && npm exec jest test/unit/lib/smalruby-original-sprites.test.js"

# トレードマーク sprite が混入していないことを確認
docker compose run --rm app bash -c "cd packages/scratch-gui && npm exec jest test/unit/lib/removed-trademarks.test.js"
```

**消失している場合の復元**: 過去コミット `f2b5c09e5b` (sprites) /
`1c3f91a216` (costumes) を参照し、エントリを再追加する。アセット PNG は
`packages/scratch-gui/static/smalruby-assets/` に保持されている。

**トレードマーク sprite が紛れ込んでいる場合**: 対象は
`Cat`, `Cat Flying`, `Gobo`, `Pico`, `Pico Walking`, `Nano`, `Tera`,
`Giga`, `Giga Walking`。`removed-trademarks.test.js` の `trademarkNames`
配列が現状のリストなので、増えた場合は配列を更新してから sprites.json /
costumes.json から削除する。

---

## Unexpected Conflicts

上記以外のファイルでコンフリクトが発生した場合:
Expand Down
1 change: 1 addition & 0 deletions packages/scratch-gui/.prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,7 @@ test/unit/lib/*
!test/unit/lib/rubytee-context.test.js
!test/unit/lib/screen-utils.test.js
!test/unit/lib/smalrubot-firmware-flasher.test.js
!test/unit/lib/smalruby-original-sprites.test.js
!test/unit/lib/setup-prism.js
!test/unit/lib/version-checker.test.js

Expand Down
82 changes: 52 additions & 30 deletions packages/scratch-gui/src/lib/libraries/costumes.json
Original file line number Diff line number Diff line change
Expand Up @@ -2000,36 +2000,6 @@
"mammal"
]
},
{
"name": "Cat Flying-a",
"assetId": "a1ab94c8172c3b97ed9a2bf7c32172cd",
"md5ext": "a1ab94c8172c3b97ed9a2bf7c32172cd.svg",
"dataFormat": "svg",
"bitmapResolution": 1,
"rotationCenterX": 55,
"rotationCenterY": 37,
"tags": [
"animals",
"cat",
"kitty",
"kitten"
]
},
{
"name": "Cat Flying-b",
"assetId": "6667936a2793aade66c765c329379ad0",
"md5ext": "6667936a2793aade66c765c329379ad0.svg",
"dataFormat": "svg",
"bitmapResolution": 1,
"rotationCenterX": 44,
"rotationCenterY": 46,
"tags": [
"animals",
"cat",
"kitty",
"kitten"
]
},
{
"name": "Catcher-a",
"assetId": "895cdda4f2bd9d6f50ff07188e7ce395",
Expand Down Expand Up @@ -10009,6 +9979,58 @@
"chomp"
]
},
{
"name": "Shimacat-a",
"tags": [
"animals"
],
"assetId": "851e679b8f113ee90e0d686c33fbc940",
"bitmapResolution": 2,
"dataFormat": "png",
"md5ext": "851e679b8f113ee90e0d686c33fbc940.png",
"rotationCenterX": 90,
"rotationCenterY": 100,
"rawURL": "static/smalruby-assets/851e679b8f113ee90e0d686c33fbc940.png"
},
{
"name": "Shimacat-b",
"tags": [
"animals"
],
"assetId": "57613248603bb9c5b4b767b72cd4fdef",
"bitmapResolution": 2,
"dataFormat": "png",
"md5ext": "57613248603bb9c5b4b767b72cd4fdef.png",
"rotationCenterX": 90,
"rotationCenterY": 100,
"rawURL": "static/smalruby-assets/57613248603bb9c5b4b767b72cd4fdef.png"
},
{
"name": "Shimaraby-a",
"tags": [
"animals"
],
"assetId": "ddaccfcda466a4887299feddc899fea7",
"bitmapResolution": 2,
"dataFormat": "png",
"md5ext": "ddaccfcda466a4887299feddc899fea7.png",
"rotationCenterX": 63,
"rotationCenterY": 100,
"rawURL": "static/smalruby-assets/ddaccfcda466a4887299feddc899fea7.png"
},
{
"name": "Shimaraby-b",
"tags": [
"animals"
],
"assetId": "bd0ff11c925936ed5e0363112103cd0b",
"bitmapResolution": 2,
"dataFormat": "png",
"md5ext": "bd0ff11c925936ed5e0363112103cd0b.png",
"rotationCenterX": 63,
"rotationCenterY": 100,
"rawURL": "static/smalruby-assets/bd0ff11c925936ed5e0363112103cd0b.png"
},
{
"name": "Shirt-a",
"assetId": "43e916bbe0ba7cecd08407d25ac3d104",
Expand Down
139 changes: 84 additions & 55 deletions packages/scratch-gui/src/lib/libraries/sprites.json
Original file line number Diff line number Diff line change
Expand Up @@ -3768,61 +3768,6 @@
"variables": {},
"blocks": {}
},
{
"name": "Cat Flying",
"tags": [
"animals",
"cat",
"kitty",
"kitten"
],
"isStage": false,
"costumes": [
{
"name": "Cat Flying-a",
"assetId": "a1ab94c8172c3b97ed9a2bf7c32172cd",
"md5ext": "a1ab94c8172c3b97ed9a2bf7c32172cd.svg",
"dataFormat": "svg",
"bitmapResolution": 1,
"rotationCenterX": 55,
"rotationCenterY": 37,
"tags": [
"animals",
"cat",
"kitty",
"kitten"
]
},
{
"name": "Cat Flying-b",
"assetId": "6667936a2793aade66c765c329379ad0",
"md5ext": "6667936a2793aade66c765c329379ad0.svg",
"dataFormat": "svg",
"bitmapResolution": 1,
"rotationCenterX": 44,
"rotationCenterY": 46,
"tags": [
"animals",
"cat",
"kitty",
"kitten"
]
}
],
"sounds": [
{
"name": "Pop",
"assetId": "83a9787d4cb6f3b7632b4ddfebf74367",
"md5ext": "83a9787d4cb6f3b7632b4ddfebf74367.wav",
"dataFormat": "wav",
"tags": [],
"rate": 44100,
"sampleCount": 1032
}
],
"variables": {},
"blocks": {}
},
{
"name": "Catcher",
"tags": [
Expand Down Expand Up @@ -17740,6 +17685,90 @@
"variables": {},
"blocks": {}
},
{
"name": "Shimacat",
"tags": [
"animals"
],
"isStage": false,
"variables": {},
"costumes": [
{
"assetId": "851e679b8f113ee90e0d686c33fbc940",
"name": "shimacat-a",
"bitmapResolution": 2,
"md5ext": "851e679b8f113ee90e0d686c33fbc940.png",
"dataFormat": "png",
"rotationCenterX": 90,
"rotationCenterY": 100,
"rawURL": "static/smalruby-assets/851e679b8f113ee90e0d686c33fbc940.png"
},
{
"assetId": "57613248603bb9c5b4b767b72cd4fdef",
"name": "shimacat-b",
"bitmapResolution": 2,
"md5ext": "57613248603bb9c5b4b767b72cd4fdef.png",
"dataFormat": "png",
"rotationCenterX": 90,
"rotationCenterY": 100,
"rawURL": "static/smalruby-assets/57613248603bb9c5b4b767b72cd4fdef.png"
}
],
"sounds": [
{
"assetId": "83c36d806dc92327b9e7049a565c6bff",
"name": "Meow",
"dataFormat": "wav",
"format": "",
"rate": 44100,
"sampleCount": 37376,
"md5ext": "83c36d806dc92327b9e7049a565c6bff.wav"
}
],
"blocks": {}
},
{
"name": "Shimaraby",
"tags": [
"animals"
],
"isStage": false,
"variables": {},
"costumes": [
{
"assetId": "ddaccfcda466a4887299feddc899fea7",
"name": "shimaraby-a",
"bitmapResolution": 2,
"md5ext": "ddaccfcda466a4887299feddc899fea7.png",
"dataFormat": "png",
"rotationCenterX": 63,
"rotationCenterY": 100,
"rawURL": "static/smalruby-assets/ddaccfcda466a4887299feddc899fea7.png"
},
{
"assetId": "bd0ff11c925936ed5e0363112103cd0b",
"name": "shimaraby-b",
"bitmapResolution": 2,
"md5ext": "bd0ff11c925936ed5e0363112103cd0b.png",
"dataFormat": "png",
"rotationCenterX": 63,
"rotationCenterY": 100,
"rawURL": "static/smalruby-assets/bd0ff11c925936ed5e0363112103cd0b.png"
}
],
"sounds": [
{
"assetId": "3b8236bbb288019d93ae38362e865972",
"name": "Chirp",
"dataFormat": "wav",
"format": "adpcm",
"rate": 22050,
"sampleCount": 6097,
"md5ext": "3b8236bbb288019d93ae38362e865972.wav"
}
],
"blocks": {}
},
{
"name": "Shirt",
"tags": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import costumeLibraryContent from '../../../src/lib/libraries/costumes.json';
import spriteLibraryContent from '../../../src/lib/libraries/sprites.json';

const trademarkNames = ['Cat', 'Cat-Flying', 'Gobo', 'Pico', 'Pico Walking', 'Nano', 'Tera', 'Giga', 'Giga Walking'];
const trademarkNames = ['Cat', 'Cat Flying', 'Gobo', 'Pico', 'Pico Walking', 'Nano', 'Tera', 'Giga', 'Giga Walking'];

describe('Removed trademarks (ex: Scratch Cat)', () => {
test('Removed trademark sprites', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/**
* Verifies that Smalruby's original sprites/costumes (Shimaraby, Shimacat) are
* present in the sprite/costume libraries. Regression guard for issue #688:
* upstream merges silently overwrite these libraries and wipe the entries.
*/
import costumeLibraryContent from '../../../src/lib/libraries/costumes.json';
import spriteLibraryContent from '../../../src/lib/libraries/sprites.json';

const requiredSprites = ['Shimaraby', 'Shimacat'];
const requiredCostumes = ['Shimaraby-a', 'Shimaraby-b', 'Shimacat-a', 'Shimacat-b'];

describe('Smalruby original sprites/costumes', () => {
test('sprite library contains Shimaraby and Shimacat', () => {
const spriteNames = spriteLibraryContent.map((sprite) => sprite.name);
for (const name of requiredSprites) {
expect(spriteNames).toContain(name);
}
});

test('costume library contains Shimaraby-a/b and Shimacat-a/b', () => {
const costumeNames = costumeLibraryContent.map((costume) => costume.name);
for (const name of requiredCostumes) {
expect(costumeNames).toContain(name);
}
});

test('Shimaraby/Shimacat sprite costumes reference smalruby-assets PNGs', () => {
const expectedRawURLs = {
Shimaraby: [
'static/smalruby-assets/ddaccfcda466a4887299feddc899fea7.png',
'static/smalruby-assets/bd0ff11c925936ed5e0363112103cd0b.png',
],
Shimacat: [
'static/smalruby-assets/851e679b8f113ee90e0d686c33fbc940.png',
'static/smalruby-assets/57613248603bb9c5b4b767b72cd4fdef.png',
],
};
for (const spriteName of requiredSprites) {
const sprite = spriteLibraryContent.find((s) => s.name === spriteName);
expect(sprite).toBeDefined();
const rawURLs = sprite.costumes.map((c) => c.rawURL);
expect(rawURLs).toEqual(expectedRawURLs[spriteName]);
}
});
});
Loading