Skip to content

REUSE headers in Ganimed namespace#395

Open
HyperB1 wants to merge 17 commits into
masterfrom
reuse
Open

REUSE headers in Ganimed namespace#395
HyperB1 wants to merge 17 commits into
masterfrom
reuse

Conversation

@HyperB1

@HyperB1 HyperB1 commented May 31, 2026

Copy link
Copy Markdown
Member

Описание PR

Добавление комментария-заголовка к каждому файлу в директориях Ганимеда с чётким обозначением лицензии и правообладателей в частичной соответствии со спецификацией REUSE.
Для полного соответствия надо было бы добавить такие заголовки в весь репозиторий, что могло бы создать проблемы с обратной совместимостью, так что я решил остановиться только на субдиректориях нашего проекта (Ganimed).
Подробнее: https://reuse.software/

Технические детали

SPDX-FileCopyrightText обозначает правообладателя/ей этого файла в формате год правообладатель <контактнаяинформация>.
SPDX-License-Identifier обозначает лицензию/и по которой/ым распространяется этот файл в формате SPDX.

Чек-лист

  • PR полностью завершён и мне не нужна помощь, чтобы его закончить.
  • Я запускал локальный сервер со своими изменениями, всё протестировал, и всё работает как должно.

План форматирования файлов директорий Ганимеда:

  • Добавить заголовки REUSE в файлы
  • Добавить скрипт на автоматическое выставление заголовков
  • Добавить папку LICENSES с копиями лицензий
  • Заменить CRLF на LF
  • Заменить все TAB на пробелы
  • Стандартизировать стиль отступов
  • Убрать пробелы на конце строк
  • Проверить наличие одного переноса строки на конце каждого файла
  • Обновить информацию о лицензиях в README
  • Добавить полноценное руководство по контрибьюту
  • Сжать .png (с помощью oxipng) и .ogg (с помощью oprivorbis) файлы без потери качества

namespace-wide only REUSE headers implementation without moving the licenses
See https://reuse.software/

Also reformatted EOL from CRLF to LF in _Ganimed folders.
@HyperB1 HyperB1 added A: GitHub/Workflows Area: Изменение в рабочем процессе репозитория GitHub P3: Standard Стандартный приоритет рассмотрения T: Maintenance Type: Синхронизация с апстримом, обновления чейнджлога и пр. labels May 31, 2026
@coderabbitai

coderabbitai Bot commented May 31, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Too many files!

This PR contains 278 files, which is 128 over the limit of 150.

To get a review, narrow the scope:
• coderabbit review --type committed # exclude uncommitted changes
• coderabbit review --dir # limit to a subdirectory
• coderabbit review --base # compare against a closer base

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 0e0f0476-9185-4105-8439-a5caec120e3c

📥 Commits

Reviewing files that changed from the base of the PR and between 298404a and 90da70b.

⛔ Files ignored due to path filters (22)
  • Resources/Audio/_Ganimed/Items/holster_eject.ogg is excluded by !**/*.ogg
  • Resources/Audio/_Ganimed/Items/shower_running.ogg is excluded by !**/*.ogg
  • Resources/Audio/_Ganimed/Items/shower_toggle.ogg is excluded by !**/*.ogg
  • Resources/Audio/_Ganimed/Lobby/Garoad-A-Neon-Glow-Lights-the-Way_1.ogg is excluded by !**/*.ogg
  • Resources/Audio/_Ganimed/Lobby/Garoad-Safe-Haven.ogg is excluded by !**/*.ogg
  • Resources/Audio/_Ganimed/Lobby/Garoad-Umemoto.ogg is excluded by !**/*.ogg
  • Resources/Audio/_Ganimed/Lobby/Garoad-Where-Do-I-Go-from-Here_63.ogg is excluded by !**/*.ogg
  • Resources/Audio/_Ganimed/Lobby/Garoad-You_ve-Got-Me_1.ogg is excluded by !**/*.ogg
  • Resources/Audio/_Ganimed/Lobby/Get-Up-N-FIGHT.ogg is excluded by !**/*.ogg
  • Resources/Audio/_Ganimed/Lobby/HumanMusic.ogg is excluded by !**/*.ogg
  • Resources/Audio/_Ganimed/Lobby/crazy-necross.ogg is excluded by !**/*.ogg
  • Resources/Audio/_Ganimed/Lobby/evacuate.ogg is excluded by !**/*.ogg
  • Resources/Audio/_Ganimed/Lobby/glorx-theme.ogg is excluded by !**/*.ogg
  • Resources/Audio/_Ganimed/Lobby/hackers.ogg is excluded by !**/*.ogg
  • Resources/Audio/_Ganimed/Lobby/mass-effect.ogg is excluded by !**/*.ogg
  • Resources/Audio/_Ganimed/Lobby/morning-on-the-kamchatka.ogg is excluded by !**/*.ogg
  • Resources/Audio/_Ganimed/Lobby/our-flag-was-still-there.ogg is excluded by !**/*.ogg
  • Resources/Audio/_Ganimed/Lobby/revolution.ogg is excluded by !**/*.ogg
  • Resources/Audio/_Ganimed/Lobby/silicon-dreams.ogg is excluded by !**/*.ogg
  • Resources/Audio/_Ganimed/Lobby/space_oddity.ogg is excluded by !**/*.ogg
  • Resources/Audio/_Ganimed/Weapons/mortar_long_whistle.ogg is excluded by !**/*.ogg
  • Resources/Audio/_Ganimed/Weapons/watering.ogg is excluded by !**/*.ogg
📒 Files selected for processing (278)
  • .editorconfig
  • .github/CODEOWNERS
  • .github/ISSUE_TEMPLATE/01_report_issue.yml
  • .github/ISSUE_TEMPLATE/02_mapping_issue.yml
  • .github/ISSUE_TEMPLATE/bug_report.yml
  • .github/ISSUE_TEMPLATE/config.yml
  • .github/PULL_REQUEST_TEMPLATE.md
  • .github/workflows/reuse-updater.yml
  • Content.Server/_Ganimed/CartridgeLoader/Cartridges/AtmosTekCartridgeComponent.cs
  • Content.Server/_Ganimed/CartridgeLoader/Cartridges/AtmosTekCartridgeSystem.cs
  • Content.Server/_Ganimed/Paper/SignAttemptEvent.cs
  • Content.Server/_Ganimed/Paper/SignatureSystem.cs
  • Content.Server/_Ganimed/SponsorLoadout/DebugSponsorPrototype.cs
  • Content.Server/_Ganimed/Traits/Assorted/IncognitoSystem.cs
  • Content.Shared/_Ganimed/Preferences/Loadouts/Effects/JobRestrictedLoadoutEffect.cs
  • Content.Shared/_Ganimed/Traits/Assorted/SetIncognitoComponent.cs
  • LICENSES/AGPL-3.0-or-later.txt
  • LICENSES/CC-BY-SA-4.0.txt
  • LICENSES/MIT.txt
  • README.md
  • Resources/Audio/_Ganimed/Lobby/attributions.yml
  • Resources/Locale/en-US/_Ganimed/heretic/sacrificed.ftl
  • Resources/Locale/en-US/_Ganimed/holiday/greet/holiday-greet.ftl
  • Resources/Locale/en-US/_Ganimed/paper/signature.ftl
  • Resources/Locale/en-US/_Ganimed/station-events/events/events.ftl
  • Resources/Locale/ru-RU/_Ganimed/Chat/chatstack.ftl
  • Resources/Locale/ru-RU/_Ganimed/access/components/id-card-console-component.ftl
  • Resources/Locale/ru-RU/_Ganimed/administration/antag.ftl
  • Resources/Locale/ru-RU/_Ganimed/cartridge-loader/cartridges.ftl
  • Resources/Locale/ru-RU/_Ganimed/cyborg/cyborg_energy.ftl
  • Resources/Locale/ru-RU/_Ganimed/datasets/names/military_first_leader_ussp.ftl
  • Resources/Locale/ru-RU/_Ganimed/datasets/names/military_first_nt.ftl
  • Resources/Locale/ru-RU/_Ganimed/datasets/names/military_first_ussp.ftl
  • Resources/Locale/ru-RU/_Ganimed/datasets/names/military_last_ussp.ftl
  • Resources/Locale/ru-RU/_Ganimed/flavors/flavors.ftl
  • Resources/Locale/ru-RU/_Ganimed/game-ticking/game-presets/preset-conspirator.ftl
  • Resources/Locale/ru-RU/_Ganimed/guidebook/guides.ftl
  • Resources/Locale/ru-RU/_Ganimed/headset/headset-component.ftl
  • Resources/Locale/ru-RU/_Ganimed/holiday/greet/holiday-greet.ftl
  • Resources/Locale/ru-RU/_Ganimed/job/job-names.ftl
  • Resources/Locale/ru-RU/_Ganimed/job/job-supervisors.ftl
  • Resources/Locale/ru-RU/_Ganimed/mind/role-types.ftl
  • Resources/Locale/ru-RU/_Ganimed/nutrition/components/food-sequence.ftl
  • Resources/Locale/ru-RU/_Ganimed/paper/signature.ftl
  • Resources/Locale/ru-RU/_Ganimed/preferences/loadout-groups.ftl
  • Resources/Locale/ru-RU/_Ganimed/preferences/ui/humanoid-profile-editor.ftl
  • Resources/Locale/ru-RU/_Ganimed/prototypes/roles/antags.ftl
  • Resources/Locale/ru-RU/_Ganimed/seeds/seeds.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/catalog/fills/crates/materials.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/catalog/fills/items/belt.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/catalog/fills/supplypod/supplypod.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/clothing/back/backpacks.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/clothing/back/duffel.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/clothing/back/mods.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/clothing/back/satchel.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/clothing/belt/belts.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/clothing/ears/headsets.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/clothing/eyes/glasses.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/clothing/hands/gloves.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/clothing/head/hardhats.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/clothing/head/hardsuit-helmets.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/clothing/head/hats.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/clothing/head/helmets.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/clothing/head/misc.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/clothing/head/soft.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/clothing/multiple/cloth-wraps.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/clothing/neck/bandage.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/clothing/neck/cloaks.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/clothing/neck/mantles.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/clothing/neck/misc.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/clothing/neck/scarfs.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/clothing/neck/ties.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/clothing/outerclothing/armor.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/clothing/outerclothing/coats.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/clothing/outerclothing/hardsuits.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/clothing/outerclothing/misc.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/clothing/outerclothing/vests.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/clothing/shoes/boots.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/clothing/shoes/magboots.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/clothing/shoes/misc.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/clothing/under/shirts.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/clothing/under/socks.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/clothing/under/underpants.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/clothing/uniforms/jumpskirts.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/clothing/uniforms/jumpsuits.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/clothing/uniforms/scrubs.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/clothing/ussp.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/effects/rockets/rockets_effects.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/effects/supplypod/supplypod_effects.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/effects/triggers.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/markers/spawners/random/toy.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/markers/spawners/supplypod.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/mobs/player/humanoid.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/objects/consumable/food/meals.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/objects/consumable/food/produce.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/objects/consumable/food/soup.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/objects/devices/cartridges.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/objects/devices/pda.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/objects/fun/plushies.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/objects/misc/handy_flags.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/objects/misc/identification_cards.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/objects/misc/implanters.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/objects/misc/pen.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/objects/misc/subdermal_implants.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/objects/specific/chemistry.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/objects/specific/hydroponics/seeds.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/objects/tools/lantern.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/objects/weapons/Guns/Rifles/rifles.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/objects/weapons/melee/hammers.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/personalization/personalization_clothing.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/personalization/personalization_items.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/structures/catwalk.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/structures/doors/airlocks/double_glass_airlock.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/structures/furniture/chairs.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/structures/furniture/shower.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/structures/specific/rockets/rockets.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/structures/storage/supplypod/supplypod.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/entities/structures/wallmounts/signs/flags.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/gamerules/roundstart.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/loadouts/dummy_entities.ftl
  • Resources/Locale/ru-RU/_Ganimed/ss14-ru/prototypes/objectives/conspirator.ftl
  • Resources/Locale/ru-RU/_Ganimed/station-events/events/stray-supply-pod.ftl
  • Resources/Locale/ru-RU/_Ganimed/traits/traits.ftl
  • Resources/Locale/ru-RU/_Ganimed/verb-text.ftl
  • Resources/Prototypes/_Ganimed/Access/extended.yml
  • Resources/Prototypes/_Ganimed/Catalog/Fills/Crates/materials.yml
  • Resources/Prototypes/_Ganimed/Catalog/Fills/Items/belt.yml
  • Resources/Prototypes/_Ganimed/Catalog/Fills/stray_supply_pod.yml
  • Resources/Prototypes/_Ganimed/Catalog/SupplyPod/supply_pod.yml
  • Resources/Prototypes/_Ganimed/Catalog/rockets.yml
  • Resources/Prototypes/_Ganimed/Datasets/Names/military.yml
  • Resources/Prototypes/_Ganimed/Entities/Clothing/Back/backpacks.yml
  • Resources/Prototypes/_Ganimed/Entities/Clothing/Back/duffel.yml
  • Resources/Prototypes/_Ganimed/Entities/Clothing/Back/mods.yml
  • Resources/Prototypes/_Ganimed/Entities/Clothing/Back/satchels.yml
  • Resources/Prototypes/_Ganimed/Entities/Clothing/Belt/belts.yml
  • Resources/Prototypes/_Ganimed/Entities/Clothing/Belt/pouches.yml
  • Resources/Prototypes/_Ganimed/Entities/Clothing/Eyes/glasses.yml
  • Resources/Prototypes/_Ganimed/Entities/Clothing/Hands/gloves.yml
  • Resources/Prototypes/_Ganimed/Entities/Clothing/Hands/modsuit_gloves.yml
  • Resources/Prototypes/_Ganimed/Entities/Clothing/Head/hardhats.yml
  • Resources/Prototypes/_Ganimed/Entities/Clothing/Head/hardsuit-helmets.yml
  • Resources/Prototypes/_Ganimed/Entities/Clothing/Head/hats.yml
  • Resources/Prototypes/_Ganimed/Entities/Clothing/Head/helmets.yml
  • Resources/Prototypes/_Ganimed/Entities/Clothing/Head/misc.yml
  • Resources/Prototypes/_Ganimed/Entities/Clothing/Head/modsuit-helmets.yml
  • Resources/Prototypes/_Ganimed/Entities/Clothing/Head/soft.yml
  • Resources/Prototypes/_Ganimed/Entities/Clothing/Multiple/cloth_wraps.yml
  • Resources/Prototypes/_Ganimed/Entities/Clothing/Neck/bandage.yml
  • Resources/Prototypes/_Ganimed/Entities/Clothing/Neck/cloaks.yml
  • Resources/Prototypes/_Ganimed/Entities/Clothing/Neck/mantles.yml
  • Resources/Prototypes/_Ganimed/Entities/Clothing/Neck/misc.yml
  • Resources/Prototypes/_Ganimed/Entities/Clothing/Neck/scarfs.yml
  • Resources/Prototypes/_Ganimed/Entities/Clothing/Neck/ties.yml
  • Resources/Prototypes/_Ganimed/Entities/Clothing/OuterClothing/armor.yml
  • Resources/Prototypes/_Ganimed/Entities/Clothing/OuterClothing/coats.yml
  • Resources/Prototypes/_Ganimed/Entities/Clothing/OuterClothing/hardsuits.yml
  • Resources/Prototypes/_Ganimed/Entities/Clothing/OuterClothing/misc.yml
  • Resources/Prototypes/_Ganimed/Entities/Clothing/OuterClothing/modsuits.yml
  • Resources/Prototypes/_Ganimed/Entities/Clothing/OuterClothing/vests.yml
  • Resources/Prototypes/_Ganimed/Entities/Clothing/Shoes/boots.yml
  • Resources/Prototypes/_Ganimed/Entities/Clothing/Shoes/misc.yml
  • Resources/Prototypes/_Ganimed/Entities/Clothing/Shoes/modsuit_boots.yml
  • Resources/Prototypes/_Ganimed/Entities/Clothing/Under/pants.yml
  • Resources/Prototypes/_Ganimed/Entities/Clothing/Under/shirt.yml
  • Resources/Prototypes/_Ganimed/Entities/Clothing/Under/socks.yml
  • Resources/Prototypes/_Ganimed/Entities/Clothing/Uniforms/color_turtlenecks.yml
  • Resources/Prototypes/_Ganimed/Entities/Clothing/Uniforms/color_turtlenecks_skirt.yml
  • Resources/Prototypes/_Ganimed/Entities/Clothing/Uniforms/jumpskirts.yml
  • Resources/Prototypes/_Ganimed/Entities/Clothing/Uniforms/jumpsuits.yml
  • Resources/Prototypes/_Ganimed/Entities/Clothing/Uniforms/scrubs.yml
  • Resources/Prototypes/_Ganimed/Entities/Effects/Rockets/rockets_effects.yml
  • Resources/Prototypes/_Ganimed/Entities/Effects/SupplyPod/base_supplypod_effects.yml
  • Resources/Prototypes/_Ganimed/Entities/Effects/SupplyPod/supplypod_effects.yml
  • Resources/Prototypes/_Ganimed/Entities/Effects/triggers.yml
  • Resources/Prototypes/_Ganimed/Entities/Markers/Spawners/Random/toy.yml
  • Resources/Prototypes/_Ganimed/Entities/Markers/Spawners/supplypod.yml
  • Resources/Prototypes/_Ganimed/Entities/Mobs/Player/humanoid.yml
  • Resources/Prototypes/_Ganimed/Entities/Mobs/Player/ussp_army.yml
  • Resources/Prototypes/_Ganimed/Entities/Objects/Consumable/Food/meals.yml
  • Resources/Prototypes/_Ganimed/Entities/Objects/Consumable/Food/produce.yml
  • Resources/Prototypes/_Ganimed/Entities/Objects/Consumable/Food/soup.yml
  • Resources/Prototypes/_Ganimed/Entities/Objects/Devices/cartridges.yml
  • Resources/Prototypes/_Ganimed/Entities/Objects/Devices/pda.yml
  • Resources/Prototypes/_Ganimed/Entities/Objects/Fun/plushies.yml
  • Resources/Prototypes/_Ganimed/Entities/Objects/Misc/handy_flags.yml
  • Resources/Prototypes/_Ganimed/Entities/Objects/Misc/identification_cards.yml
  • Resources/Prototypes/_Ganimed/Entities/Objects/Misc/implanters.yml
  • Resources/Prototypes/_Ganimed/Entities/Objects/Misc/pens.yml
  • Resources/Prototypes/_Ganimed/Entities/Objects/Misc/subdermal_implants.yml
  • Resources/Prototypes/_Ganimed/Entities/Objects/Specific/Hydroponics/seeds.yml
  • Resources/Prototypes/_Ganimed/Entities/Objects/Specific/chemistry.yml
  • Resources/Prototypes/_Ganimed/Entities/Objects/Tools/lantern.yml
  • Resources/Prototypes/_Ganimed/Entities/Objects/Weapons/Guns/Rifles/rifles.yml
  • Resources/Prototypes/_Ganimed/Entities/Objects/Weapons/Melee/breaching_hammer.yml
  • Resources/Prototypes/_Ganimed/Entities/Personalization/personalization_clothing.yml
  • Resources/Prototypes/_Ganimed/Entities/Personalization/personalization_items.yml
  • Resources/Prototypes/_Ganimed/Entities/Structures/Doors/Airlocks/double_glass_airlock.yml
  • Resources/Prototypes/_Ganimed/Entities/Structures/Furniture/chairs.yml
  • Resources/Prototypes/_Ganimed/Entities/Structures/Furniture/shower.yml
  • Resources/Prototypes/_Ganimed/Entities/Structures/Specific/Rockets/base_rocket.yml
  • Resources/Prototypes/_Ganimed/Entities/Structures/Specific/Rockets/rocket.yml
  • Resources/Prototypes/_Ganimed/Entities/Structures/Storage/SupplyPod/base_supply_pod.yml
  • Resources/Prototypes/_Ganimed/Entities/Structures/Storage/SupplyPod/supply_pod_capsule.yml
  • Resources/Prototypes/_Ganimed/Entities/Structures/Wallmounts/flags.yml
  • Resources/Prototypes/_Ganimed/Entities/Structures/catwalk.yml
  • Resources/Prototypes/_Ganimed/Flavors/flavors.yml
  • Resources/Prototypes/_Ganimed/GameRules/events.yml
  • Resources/Prototypes/_Ganimed/Guidebook/rules.yml
  • Resources/Prototypes/_Ganimed/Hydroponics/seeds.yml
  • Resources/Prototypes/_Ganimed/Loadouts/Jobs/Cargo/cargo_technician.yml
  • Resources/Prototypes/_Ganimed/Loadouts/Jobs/Cargo/quartermaster.yml
  • Resources/Prototypes/_Ganimed/Loadouts/Jobs/Cargo/salvage_specialist.yml
  • Resources/Prototypes/_Ganimed/Loadouts/Jobs/Centcom/centcom.yml
  • Resources/Prototypes/_Ganimed/Loadouts/Jobs/Civilian/bartender.yml
  • Resources/Prototypes/_Ganimed/Loadouts/Jobs/Civilian/botanist.yml
  • Resources/Prototypes/_Ganimed/Loadouts/Jobs/Civilian/chaplain.yml
  • Resources/Prototypes/_Ganimed/Loadouts/Jobs/Civilian/chef.yml
  • Resources/Prototypes/_Ganimed/Loadouts/Jobs/Civilian/clown.yml
  • Resources/Prototypes/_Ganimed/Loadouts/Jobs/Civilian/janitor.yml
  • Resources/Prototypes/_Ganimed/Loadouts/Jobs/Civilian/lawyer.yml
  • Resources/Prototypes/_Ganimed/Loadouts/Jobs/Civilian/librarian.yml
  • Resources/Prototypes/_Ganimed/Loadouts/Jobs/Civilian/mime.yml
  • Resources/Prototypes/_Ganimed/Loadouts/Jobs/Civilian/musician.yml
  • Resources/Prototypes/_Ganimed/Loadouts/Jobs/Civilian/passenger.yml
  • Resources/Prototypes/_Ganimed/Loadouts/Jobs/Command/adjutant.yml
  • Resources/Prototypes/_Ganimed/Loadouts/Jobs/Command/captain.yml
  • Resources/Prototypes/_Ganimed/Loadouts/Jobs/Command/head_of_personnel.yml
  • Resources/Prototypes/_Ganimed/Loadouts/Jobs/Engineering/atmospheric_technician.yml
  • Resources/Prototypes/_Ganimed/Loadouts/Jobs/Engineering/chief_engineer.yml
  • Resources/Prototypes/_Ganimed/Loadouts/Jobs/Engineering/station_engineer.yml
  • Resources/Prototypes/_Ganimed/Loadouts/Jobs/Medical/chemist.yml
  • Resources/Prototypes/_Ganimed/Loadouts/Jobs/Medical/chief_medical_officer.yml
  • Resources/Prototypes/_Ganimed/Loadouts/Jobs/Medical/medical_doctor.yml
  • Resources/Prototypes/_Ganimed/Loadouts/Jobs/Medical/paramedic.yml
  • Resources/Prototypes/_Ganimed/Loadouts/Jobs/Science/research_director.yml
  • Resources/Prototypes/_Ganimed/Loadouts/Jobs/Science/scientist.yml
  • Resources/Prototypes/_Ganimed/Loadouts/Jobs/Security/brigmedic.yml
  • Resources/Prototypes/_Ganimed/Loadouts/Jobs/Security/detective.yml
  • Resources/Prototypes/_Ganimed/Loadouts/Jobs/Security/head_of_security.yml
  • Resources/Prototypes/_Ganimed/Loadouts/Jobs/Security/pilot.yml
  • Resources/Prototypes/_Ganimed/Loadouts/Jobs/Security/security_cadet.yml
  • Resources/Prototypes/_Ganimed/Loadouts/Jobs/Security/security_officer.yml
  • Resources/Prototypes/_Ganimed/Loadouts/Jobs/Security/warden.yml
  • Resources/Prototypes/_Ganimed/Loadouts/Jobs/Wildcards/boxer.yml
  • Resources/Prototypes/_Ganimed/Loadouts/Jobs/Wildcards/psychologist.yml
  • Resources/Prototypes/_Ganimed/Loadouts/Miscellaneous/glasses.yml
  • Resources/Prototypes/_Ganimed/Loadouts/Miscellaneous/spare_clothing.yml
  • Resources/Prototypes/_Ganimed/Loadouts/Miscellaneous/trinkets.yml
  • Resources/Prototypes/_Ganimed/Loadouts/Miscellaneous/undergarments.yml
  • Resources/Prototypes/_Ganimed/Loadouts/dummy_entities.yml
  • Resources/Prototypes/_Ganimed/Loadouts/loadout_groups.yml
  • Resources/Prototypes/_Ganimed/Loadouts/sponsor_loadout.yml
  • Resources/Prototypes/_Ganimed/Maps/civilstation.yml
  • Resources/Prototypes/_Ganimed/Recipes/Construction/Graphs/structures/supplypod.yml
  • Resources/Prototypes/_Ganimed/Recipes/Cooking/food_sequence_element.yml
  • Resources/Prototypes/_Ganimed/Recipes/Cooking/meal_recipes.yml
  • Resources/Prototypes/_Ganimed/Roles/Fun/ussp.yml
  • Resources/Prototypes/_Ganimed/Sponsors/debug_sponsors.yml
  • Resources/Prototypes/_Ganimed/StatusEffects/job.yml
  • Resources/Prototypes/_Ganimed/Traits/categories.yml
  • Resources/Prototypes/_Ganimed/Traits/disabilities.yml
  • Resources/Prototypes/_Ganimed/holidays.yml
  • Resources/ServerInfo/_Ganimed/Guidebook/ServerRules/Rule0-0.xml
  • Resources/ServerInfo/_Ganimed/Guidebook/ServerRules/Rule0-1.xml
  • Resources/ServerInfo/_Ganimed/Guidebook/ServerRules/Rule0-2.xml
  • Resources/ServerInfo/_Ganimed/Guidebook/ServerRules/Rule0-3.xml
  • Resources/ServerInfo/_Ganimed/Guidebook/ServerRules/Rule1-0.xml
  • Resources/ServerInfo/_Ganimed/Guidebook/ServerRules/Rule1-1.xml
  • Resources/ServerInfo/_Ganimed/Guidebook/ServerRules/Rule1-10.xml
  • Resources/ServerInfo/_Ganimed/Guidebook/ServerRules/Rule1-11.xml
  • Resources/ServerInfo/_Ganimed/Guidebook/ServerRules/Rule1-12.xml
  • Resources/ServerInfo/_Ganimed/Guidebook/ServerRules/Rule1-13.xml
  • Resources/ServerInfo/_Ganimed/Guidebook/ServerRules/Rule1-14.xml
  • Resources/ServerInfo/_Ganimed/Guidebook/ServerRules/Rule1-15.xml
  • Resources/ServerInfo/_Ganimed/Guidebook/ServerRules/Rule1-2.xml
  • Resources/ServerInfo/_Ganimed/Guidebook/ServerRules/Rule1-3.xml
  • Resources/ServerInfo/_Ganimed/Guidebook/ServerRules/Rule1-4.xml

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added size/M S: Needs Review Status: Требуется рассмотрение Changes: Localization Изменения затрагивают локализацию. and removed size/M S: Needs Review Status: Требуется рассмотрение labels May 31, 2026
@github-actions github-actions Bot added the size/M label Jun 1, 2026
@HyperB1 HyperB1 marked this pull request as ready for review June 5, 2026 20:42
@github-actions github-actions Bot added the S: Needs Review Status: Требуется рассмотрение label Jun 5, 2026
@HyperB1

HyperB1 commented Jun 5, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review --dir .github

@coderabbitai

coderabbitai Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# List all files in the .github directory
tree .github
echo "---"
# List files with find for completeness
find .github -type f | sort

Length of output: 3526


🏁 Script executed:

#!/bin/bash
# Read top-level .github files
echo "=== CODEOWNERS ==="
cat .github/CODEOWNERS
echo ""
echo "=== FUNDING.yml ==="
cat .github/FUNDING.yml
echo ""
echo "=== PULL_REQUEST_TEMPLATE.md ==="
cat .github/PULL_REQUEST_TEMPLATE.md
echo ""
echo "=== config.yml ==="
cat .github/config.yml
echo ""
echo "=== labeler.yml ==="
cat .github/labeler.yml
echo ""
echo "=== rsi-schema.json ==="
cat .github/rsi-schema.json
echo ""
echo "=== ISSUE_TEMPLATE/01_report_issue.yml ==="
cat .github/ISSUE_TEMPLATE/01_report_issue.yml
echo ""
echo "=== ISSUE_TEMPLATE/02_mapping_issue.yml ==="
cat .github/ISSUE_TEMPLATE/02_mapping_issue.yml
echo ""
echo "=== ISSUE_TEMPLATE/bug_report.yml ==="
cat .github/ISSUE_TEMPLATE/bug_report.yml
echo ""
echo "=== ISSUE_TEMPLATE/config.yml ==="
cat .github/ISSUE_TEMPLATE/config.yml
echo ""
echo "=== Schemas/mapfile_requirements.txt ==="
cat .github/Schemas/mapfile_requirements.txt
echo ""
echo "=== Schemas/rga.yml ==="
cat .github/Schemas/rga.yml
echo ""
echo "=== Schemas/rga_requirements.txt ==="
cat .github/Schemas/rga_requirements.txt
echo ""
echo "=== Schemas/rga_validators.py ==="
cat .github/Schemas/rga_validators.py

Length of output: 18573


🏁 Script executed:

#!/bin/bash
# Read workflow files
for f in .github/workflows/*.yml .github/workflows/*.off; do
  echo "=== $f ==="
  cat "$f"
  echo ""
done

Length of output: 57380



@HyperB1 Вот полный обзор директории .github:


Обзор .github

🔴 Критические проблемы

1. workflows/reuse-updater.yml — сбой при push-событии

Воркфлоу триггерится на push в ветки (master, staging, stable), но в шаге Get Changed Files and PR Info используется PR_NUMBER, который будет пустым при пуше (а не при PR). Вызов GitHub API с пустым номером PR завершится ошибкой.

Решение: добавить условие if: github.event_name == 'pull_request' на весь job, или ограничить триггеры только pull_request:

on:
  pull_request:
    types: [ opened, reopened, synchronize, ready_for_review ]
    paths:
    - '**Ganimed/**'
    # ...

2. workflows/benchmarks.yml — устаревший синтаксис ::set-output

Line 18 использует устаревшую команду, поддержка которой прекращена GitHub:

echo "::set-output name=out::$(git rev-parse HEAD)"

Замените на:

echo "out=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT

🟠 Проблемы безопасности

3. ISSUE_TEMPLATE/config.yml — уязвимости сообщаются в публичный канал

Ссылка "Сообщить об уязвимости" указывает на тот же публичный канал Discord, что и "Предложение". Это опасно: серьёзные эксплойты не должны раскрываться публично. Нужно использовать приватный канал/DM.

4. Непривязанные версии сторонних actions

Для безопасности цепочки поставок ПО действия сторонних разработчиков следует привязывать к конкретным SHA коммитов, а не к тегам (например, tj-actions/changed-files@v46.0.5 в check-trailing-whitespace.yml, softprops/action-gh-release@v1 в create-release.yml). Теги могут быть перемещены злоумышленником.


🟡 Качество и консистентность

5. BOM-символы в YAML-файлах (иронично в контексте данного PR о форматировании)

Следующие файлы начинаются с символа BOM (\uFEFF), что может вызвать проблемы с парсингом YAML:

  • .github/labeler.yml
  • .github/workflows/benchmarks.yml
  • .github/workflows/build-map-renderer.yml
  • .github/workflows/check-crlf.yml
  • .github/workflows/labeler-needsreview.yml
  • .github/workflows/test-packaging.yml
  • .github/workflows/labeler-untriaged.off

Команда для исправления:

sed -i 's/^\xEF\xBB\xBF//' <file>

6. Дублирующиеся воркфлоу уведомлений Discord

Присутствуют два практически идентичных воркфлоу:

  • adt-pr-to-discord.yml (использует pull_request_target + Tools/ADT/pr_to_discord.py)
  • pr-to-discord.yml (использует pull_request + Tools/ganimed/pr_to_discord.py)

Следует оставить один актуальный и удалить другой.

7. workflows/build-test-debug.yml — мусорные артефакты

  • Line 1: name: Build & Test Debug # test — отладочный комментарий # test в имени воркфлоу
  • Условие if: содержит ссылки на ботов других форков: github.actor != 'DeltaV-Bot' && github.actor != 'SimpleStation14'

8. Несогласованные версии actions

Action Старая версия Новая версия
actions/checkout v3.6.0 v4.2.2
actions/setup-dotnet v3.2.0 v4.1.0
actions/setup-python v3 v5

Файлы со старыми версиями: adt-build-test-debug-win.yml, build-test-debug.yml, publish-testing.yml, auto-cl-update-atd.yml.

9. Устаревшие upstream-ссылки

  • .github/config.yml — ссылается на Project Board организации space-wizards (project: 2), вероятно не используется в этом форке
  • labeler.yml — содержит паттерн Resources/Prototypes/Corvax/Maps/** (от upstream)
  • benchmarks.yml — жёстко прописан https://github.com/space-wizards/space-station-14.git вместо репозитория форка
  • update-wiki.yml — содержит пути ADT/Reagents, ADT/Chemistry и т.д., специфичные для другого форка

10. Несогласованность языков в ISSUE_TEMPLATE

  • 01_report_issue.yml и 02_mapping_issue.yml — на английском
  • bug_report.yml — на русском

Рекомендуется привести все шаблоны к одному языку (русскому, раз это русскоязычный проект).

11. locale-check.yml — отсутствует проверка черновика

В отличие от других воркфлоу, в locale-check.yml отсутствует условие if: github.event.pull_request.draft == false.


ℹ️ Прочие замечания

  • FUNDING.yml: все поля — незаполненные плейсхолдеры кроме custom. Можно почистить, оставив только используемые поля.
  • reuse-updater.yml — единственный workflow-файл в этом PR, который имеет REUSE-заголовок. Остальные workflows не покрыты (возможно намеренно, т.к. .github/ находится вне Ganimed-директорий).

@HyperB1

HyperB1 commented Jun 5, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review --dir Tools/ganimed

@coderabbitai

coderabbitai Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
echo "=== Directory tree ==="
tree Tools/ganimed
echo ""
echo "=== All files ==="
find Tools/ganimed -type f | sort

Length of output: 496


🏁 Script executed:

#!/bin/bash
# Read all files in Tools/ganimed
find Tools/ganimed -type f | sort | while read f; do
  echo "=== $f ==="
  cat "$f"
  echo ""
done

Length of output: 48292



@HyperB1 Вот полный обзор директории Tools/ganimed:


Обзор Tools/ganimed

🔴 Критические проблемы

1. Shebang после REUSE-заголовка (все три исполняемых скрипта)

В apply_reuse_headers.py, pr_to_discord.py и update_pr_reuse_headers.py строка #!/usr/bin/env python3 расположена после комментариев REUSE-заголовка, а не в самой первой строке файла. Ядро Linux читает shebang только со строки 1, поэтому при прямом запуске (./script.py) скрипт не будет выполнен как Python — он вернёт ошибку интерпретатора.

Варианты исправления:

  • Перенести shebang перед REUSE-заголовком (противоречит спецификации REUSE, которая требует, чтобы SPDX-* были как можно раньше).
  • Или хранить shebang в строке 1, затем REUSE-заголовок, как того требует REUSE spec §3.1: shebang разрешён перед заголовком.
    #!/usr/bin/env python3
    # SPDX-FileCopyrightText: ...
    # SPDX-License-Identifier: AGPL-3.0-or-later

2. apply_reuse_headers.py — добавляет текущего git-пользователя как автора в каждый файл

В функции process_file текущий git-пользователь добавляется в авторы независимо от реального авторства файла. При запуске скрипта в CI (где автором является бот) это приведёт к некорректным SPDX-FileCopyrightText строкам по всему репозиторию.


🟠 Проблемы корректности

3. pr_to_discord.py — некорректная валидация Discord webhook

test_discord_webhook() выполняет GET-запрос, но Discord webhooks отвечают 405 Method Not Allowed на GET. Проверка if resp.status_code in (401, 403, 404) никогда не срабатывает корректно:

# Текущий код (некорректный):
resp = requests.get(url, timeout=5)
if resp.status_code in (401, 403, 404):
    return False

# Более надёжная проверка:
resp = requests.post(url, json={"embeds": []}, timeout=5)
if resp.status_code not in (200, 204):
    return False

4. pr_to_discord.pyextract_coauthors() определена, но нигде не вызывается

Функция extract_coauthors присутствует в коде, но в main() не используется. Соавторы из тела PR не извлекаются.

5. update_pr_reuse_headers.py — чувствительность к регистру в паттернах

На Linux оператор in чувствителен к регистру. Паттерн "enterprise" не совпадёт с путём Enterprise/foo.cs, а "ganimed" — с Ganimed/. Это может привести к тому, что файлы получат неправильную лицензию MIT вместо AGPL.

Исправление: привести пути к нижнему регистру перед сравнением:

def matches_pattern(file_path, pattern):
    normalized_path = file_path.replace("\\", "/").lower()
    pattern_lower = pattern.lower()
    # ... остальная логика

6. update_pr_reuse_headers.py — изменённые файлы с существующим заголовком не обновляются

if existing_license:
    print(f"Skipping {file_path} - already has REUSE header")
    return False

Если файл был перемещён из upstream-директории (с MIT) в Ganimed-директорию, его заголовок не будет обновлён до AGPL. Это создаёт риск некорректного лицензирования.


🟡 Проблемы качества кода

7. Колоссальное дублирование кода между apply_reuse_headers.py и update_pr_reuse_headers.py

Оба файла содержат идентичные:

  • COMMENT_STYLES (~80 строк)
  • parse_existing_header()
  • create_header()

Это нарушает принцип DRY. Рекомендуется вынести общий код в Tools/ganimed/reuse_utils.py.

8. pr_to_discord.pydatetime.utcnow() устарел

В Python 3.12+ datetime.utcnow() объявлен устаревшим:

# Устаревший код:
datetime.utcnow().strftime('%d.%m.%Y %H:%M UTC')

# Замена:
datetime.now(timezone.utc).strftime('%d.%m.%Y %H:%M UTC')

timezone уже импортирован в файле (через from datetime import datetime), нужно просто добавить timezone в импорт.

9. pr_to_discord.py — чрезмерный таймаут и мёртвый код

  • TIMEOUT = 620 (более 10 минут) заставит CI-задачу зависать при недоступности Discord. Разумное значение: 30–60 секунд.
  • Функция smart_capitalize() отмечена комментарием # currently unused. Следует удалить её или использовать.

10. locale_check_ftl.py — проверяются только файлы из en-US

Если файл существует в ru-RU, но отсутствует в en-US, скрипт его не обнаружит:

# Текущий код — итерирует только en-US:
files = [f for f in os.listdir(lang0_path) if f.endswith(".ftl")]

# Исправление — объединить файлы из всех языков:
all_files = set()
for lang in LANGS:
    lang_path = os.path.join(LOCALE_DIR, lang)
    if os.path.isdir(lang_path):
        all_files.update(f for f in os.listdir(lang_path) if f.endswith(".ftl"))

11. locale_check_ftl.py — FTL-атрибуты не обрабатываются

Fluent поддерживает синтаксис атрибутов (message.attribute = value). Текущий KEY_RE = re.compile(r"^\s*([\w\-]+)\s*=\s*(.*)") не матчит точку, поэтому атрибуты будут молча проигнорированы вместо проверки.


ℹ️ Прочие замечания

  • update_pr_reuse_headers.py: аргументы --pr-base-sha и --pr-head-sha принимаются парсером, но помечены как (unused) и нигде не применяются. Стоит либо использовать, либо удалить.
  • requests: библиотека используется в pr_to_discord.py, но нет requirements.txt или аналогичного файла зависимостей для этой директории. Стоит добавить Tools/ganimed/requirements.txt.
  • apply_reuse_headers.py обрабатывает весь репозиторий через git ls-files, не только Ganimed-директории. Разумно добавить фильтрацию по путям через аргумент CLI.

@HyperB1

HyperB1 commented Jun 5, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai мне нужно сделать так, чтобы workflow reuse-updater.yml обновлял заголовки только у файлов в определённых папках по путям, что определены в этом файле (Ganimed, Enterprise и подобные).

@coderabbitai

coderabbitai Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
echo "=== .github/workflows/reuse-updater.yml ==="
cat .github/workflows/reuse-updater.yml
echo ""
echo "=== Tools/ganimed/update_pr_reuse_headers.py ==="
cat Tools/ganimed/update_pr_reuse_headers.py

Length of output: 17534



@HyperB1 Нужно исправление в двух местах:

  1. Основная защита — в Python-скрипте: добавить в process_file() ранний выход, если файл не совпадает ни с одним паттерном из DIRECTORY_RULES. Сейчас при отсутствии совпадения скрипт применяет дефолты (MIT, Space Station 14 Contributors) и добавляет заголовок в upstream-файлы.

  2. Дополнительный фильтр — в workflow: отфильтровывать файлы по паттернам директорий ещё до передачи в скрипт.


  • Добавить is_in_managed_directory() в update_pr_reuse_headers.py и вызвать её в process_file()
  • Добавить grep-фильтр в шаг Get Changed Files в reuse-updater.yml

  • 📌 Commit the changes to this branch

@HyperB1

HyperB1 commented Jun 5, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review --dir

@coderabbitai

coderabbitai Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
echo "=== Root-level directory tree (depth 2) ==="
tree -L 2 --dirsfirst -I '.git'
echo ""
echo "=== Root-level files only ==="
find . -maxdepth 1 -type f | sort

Length of output: 20684


🏁 Script executed:

#!/bin/bash
echo "=== LICENSES directory ==="
ls -la LICENSES/ 2>/dev/null || echo "(not found)"
echo ""
echo "=== README ==="
ls README* 2>/dev/null
echo ""
cat README.md 2>/dev/null | head -120

Length of output: 7818


🏁 Script executed:

#!/bin/bash
echo "=== .gitignore ==="
cat .gitignore 2>/dev/null | head -80
echo ""
echo "=== .editorconfig ==="
cat .editorconfig 2>/dev/null
echo ""
echo "=== Root .reuse or reuse.toml ==="
cat reuse.toml 2>/dev/null || cat .reuse/dep5 2>/dev/null || echo "(no reuse config found at root)"

Length of output: 17987


🏁 Script executed:

#!/bin/bash
# Check Ganimed-specific directories at the top level
echo "=== Ganimed-related directories ==="
find . -maxdepth 4 -type d | grep -iE 'ganimed|enterprise|ganymede' | sort | head -60
echo ""
echo "=== Sample REUSE headers in Ganimed files ==="
find . -type f \( -name "*.cs" -o -name "*.yml" -o -name "*.yaml" \) | grep -iE 'ganimed' | head -10 | while read f; do
  echo "--- $f ---"
  head -6 "$f"
  echo ""
done

Length of output: 5332



@HyperB1 Вот обзор корневой директории репозитория:


Обзор корневой директории

🟠 REUSE-совместимость

1. Отсутствует CC-BY-SA-3.0 в папке LICENSES/

В LICENSES/ есть:

  • AGPL-3.0-or-later.txt
  • CC-BY-SA-4.0.txt
  • MIT.txt

Но в файлах Resources/Audio/_Ganimed/*/attributions.yml используются CC-BY-SA-3.0 и CC-BY-NC-SA-3.0, которых нет в папке LICENSES/. Согласно REUSE spec, каждая упоминаемая лицензия должна иметь копию в LICENSES/:

LICENSES/CC-BY-SA-3.0.txt     # нужно добавить
LICENSES/CC-BY-NC-SA-3.0.txt  # нужно добавить

2. Нет reuse.toml / .reuse/dep5

Для прохождения reuse lint требуется либо конфиг reuse.toml, либо заголовки во всех файлах. Без конфига reuse lint будет сообщать об ошибках для upstream-файлов без заголовков. Если полная проверка не планируется — это ожидаемо, но стоит задокументировать.

3. Content.Server/Ganimed/ (без нижнего подчёркивания) не покрыт автообновлением заголовков

./Content.Server/Ganimed/SponsorLoadout/DebugSponsorPrototype.cs  ← нет REUSE-заголовка

Директория Ganimed/ (без _) не совпадает с паттерном _Ganimed ни в воркфлоу (ALLOWED_PATHS_PATTERN), ни в Python-скрипте (DIRECTORY_RULES). Нужно добавить паттерн Ganimed/ (без подчёркивания) в оба места, либо перенести содержимое в _Ganimed/.


🟡 Форматирование

4. BOM в .editorconfig

Файл .editorconfig сам начинается с BOM (U+FEFF), хотя в нём же прописано charset = utf-8. Иронично в контексте PR о стандартизации форматирования:

sed -i 's/^\xEF\xBB\xBF//' .editorconfig

5. Дублирующиеся файлы лицензий в корне

В корне присутствуют:

  • LICENSE-AGPLv3.TXT — дубль LICENSES/AGPL-3.0-or-later.txt
  • LICENSE-MIT.TXT — дубль LICENSES/MIT.txt

Для REUSE-совместимости каноническими являются файлы в LICENSES/. Корневые файлы — legacy, их стоит оставить ради совместимости или явно указать это в README (уже частично сделано).


🟡 Прочее

6. .gitignore содержит пути от другого форка

Resources/Prototypes/CorvaxSecrets
Resources/Textures/CorvaxSecrets
Resources/Locale/ru-RU/corvax-secrets

Это upstream-артефакты от Corvax-форка. Если они не используются — стоит убрать, чтобы не вводить в заблуждение контрибьюторов.

7. Tools/ganimed/ — отсутствует requirements.txt

Как упоминалось в предыдущем обзоре — pr_to_discord.py использует requests, но нет файла зависимостей. Воркфлоу устанавливает пакеты напрямую без requirements.txt, что затрудняет воспроизводимость.


✅ Что сделано хорошо

  • LICENSES/ содержит три основные лицензии ✅
  • README.md детально описывает лицензионную политику и REUSE-совместимость ✅
  • _Ganimed/-файлы имеют корректные REUSE-заголовки ✅
  • .editorconfig корректно настраивает end_of_line = lf, trim_trailing_whitespace = true, insert_final_newline = true

@HyperB1

HyperB1 commented Jun 5, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai в каких файлах в субдиректориях /_Ganimed/ отсутствуют переносы строки на конце файла (EOF LF) или имеются прочие проблемы с форматированием?

@coderabbitai

coderabbitai Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

python - <<'PY'
import subprocess
from pathlib import Path
from collections import defaultdict

raw = subprocess.check_output(["git", "ls-files"], text=True)
files = [p for p in raw.splitlines() if "_Ganimed" in Path(p).parts]

issues = defaultdict(list)
summary = {
    "files_scanned": 0,
    "binary_or_non_utf8": 0,
}

TEXT_EXTS = {
    ".cs", ".yml", ".yaml", ".json", ".txt", ".md", ".ftl", ".xml", ".toml",
    ".py", ".sh", ".ps1", ".csproj", ".sln", ".props", ".targets", ".resx",
    ".rsi", ".meta", ".license", ".rules", ".cfg", ".ini", ".jsonc", ".csv",
}

def is_likely_text(path: Path, data: bytes) -> bool:
    if b"\0" in data:
        return False
    if path.suffix.lower() in TEXT_EXTS:
        return True
    # Treat extensionless small/no-NUL files as text if UTF-8 decodable.
    try:
        data.decode("utf-8")
        return True
    except UnicodeDecodeError:
        return False

for rel in files:
    path = Path(rel)
    if not path.is_file():
        continue
    data = path.read_bytes()
    if not is_likely_text(path, data):
        continue

    summary["files_scanned"] += 1

    try:
        text = data.decode("utf-8-sig")
    except UnicodeDecodeError:
        issues[rel].append("non-UTF-8 / decode error")
        summary["binary_or_non_utf8"] += 1
        continue

    if data.startswith(b"\xef\xbb\xbf"):
        issues[rel].append("BOM at start")

    if data and not data.endswith(b"\n"):
        issues[rel].append("missing EOF LF")

    if b"\r\n" in data:
        issues[rel].append("CRLF line endings")
    else:
        # Only report lone CR separately if not already CRLF.
        if b"\r" in data:
            issues[rel].append("CR line endings / stray CR")

    # Multiple blank lines at EOF: file ends with at least two LF after non-newline content.
    stripped = data.rstrip(b"\n")
    if stripped and len(data) - len(stripped) > 1:
        issues[rel].append(f"multiple final LF ({len(data) - len(stripped)})")

    lines = text.splitlines(keepends=True)
    tab_lines = []
    trailing_ws_lines = []
    mixed_indent_lines = []

    for i, line in enumerate(lines, start=1):
        line_no_eol = line.rstrip("\r\n")
        if "\t" in line_no_eol:
            tab_lines.append(i)
        if line_no_eol.endswith((" ", "\t")):
            trailing_ws_lines.append(i)

        # Conservative mixed indentation check: leading whitespace contains both tabs and spaces.
        leading = line_no_eol[:len(line_no_eol) - len(line_no_eol.lstrip(" \t"))]
        if " " in leading and "\t" in leading:
            mixed_indent_lines.append(i)

    if tab_lines:
        sample = ", ".join(map(str, tab_lines[:10]))
        more = "" if len(tab_lines) <= 10 else f", ... (+{len(tab_lines)-10})"
        issues[rel].append(f"TAB characters on lines {sample}{more}")

    if trailing_ws_lines:
        sample = ", ".join(map(str, trailing_ws_lines[:10]))
        more = "" if len(trailing_ws_lines) <= 10 else f", ... (+{len(trailing_ws_lines)-10})"
        issues[rel].append(f"trailing whitespace on lines {sample}{more}")

    if mixed_indent_lines:
        sample = ", ".join(map(str, mixed_indent_lines[:10]))
        more = "" if len(mixed_indent_lines) <= 10 else f", ... (+{len(mixed_indent_lines)-10})"
        issues[rel].append(f"mixed tab/space indentation on lines {sample}{more}")

print(f"FILES_WITH_PATH_COMPONENT__Ganimed={len(files)}")
print(f"TEXT_FILES_SCANNED={summary['files_scanned']}")
print(f"FILES_WITH_ISSUES={len(issues)}")
print()

if issues:
    for rel in sorted(issues):
        print(rel)
        for issue in issues[rel]:
            print(f"  - {issue}")
else:
    print("No formatting issues found by this scan.")

print()
print("COUNTS_BY_ISSUE_TYPE")
counts = defaultdict(int)
for rel, vals in issues.items():
    for issue in vals:
        key = issue
        if issue.startswith("TAB characters"):
            key = "TAB characters"
        elif issue.startswith("trailing whitespace"):
            key = "trailing whitespace"
        elif issue.startswith("mixed tab/space"):
            key = "mixed tab/space indentation"
        elif issue.startswith("multiple final LF"):
            key = "multiple final LF"
        counts[key] += 1
for key in sorted(counts):
    print(f"{key}: {counts[key]}")
PY

Length of output: 7526



@HyperB1, по текущей PR-ветке в субдиректориях /_Ganimed/ найдено 30 файлов с проблемами форматирования из 627 проверенных текстовых файлов:

  • 28 файлов без переноса строки в конце файла (EOF LF)
  • 2 файла с пробелами/табами в конце строк (trailing whitespace)
  • CRLF, BOM, TAB-символы, mixed tab/space indentation и лишние финальные переносы этим сканом не найдены.

Нет EOF LF

Resources/Locale/en-US/_Ganimed/paper/signature.ftl
Resources/Locale/en-US/_Ganimed/station-events/events/events.ftl
Resources/Prototypes/_Ganimed/Entities/Personalization/personalization_clothing.yml
Resources/Textures/_Ganimed/Clothing/Head/Hats/officer_cap.rsi/meta.json
Resources/Textures/_Ganimed/Clothing/Head/Helmets/pilothelmet.rsi/meta.json
Resources/Textures/_Ganimed/Clothing/Head/Soft/cargopostalsoft.rsi/meta.json
Resources/Textures/_Ganimed/Clothing/Neck/Cloaks/chaplain_black.rsi/meta.json
Resources/Textures/_Ganimed/Clothing/Neck/Cloaks/chaplain_white.rsi/meta.json
Resources/Textures/_Ganimed/Clothing/Neck/Cloaks/sanabi.rsi/meta.json
Resources/Textures/_Ganimed/Clothing/Neck/Cloaks/whitebelov.rsi/meta.json
Resources/Textures/_Ganimed/Clothing/Neck/Mantles/alt_capmantle.rsi/meta.json
Resources/Textures/_Ganimed/Clothing/Neck/Mantles/bridge_officer_mantle.rsi/meta.json
Resources/Textures/_Ganimed/Clothing/Neck/Mantles/original_cemantle.rsi/meta.json
Resources/Textures/_Ganimed/Clothing/Neck/Mantles/original_rdmantle.rsi/meta.json
Resources/Textures/_Ganimed/Clothing/OuterClothing/Coats/original_labcoat_robo.rsi/meta.json
Resources/Textures/_Ganimed/Clothing/OuterClothing/WinterCoats/wintercoatseniorengineer.rsi/meta.json
Resources/Textures/_Ganimed/Clothing/OuterClothing/WinterCoats/wintercoatseniorofficer.rsi/meta.json
Resources/Textures/_Ganimed/Clothing/OuterClothing/WinterCoats/wintercoatseniorphysican.rsi/meta.json
Resources/Textures/_Ganimed/Clothing/OuterClothing/WinterCoats/wintercoatseniorresearcher.rsi/meta.json
Resources/Textures/_Ganimed/Clothing/Uniforms/Jumpskirt/cargopostal.rsi/meta.json
Resources/Textures/_Ganimed/Clothing/Uniforms/Jumpskirt/clownskirtsuit.rsi/meta.json
Resources/Textures/_Ganimed/Clothing/Uniforms/Jumpskirt/dec.rsi/meta.json
Resources/Textures/_Ganimed/Clothing/Uniforms/Jumpsuit/USSP/sponsor_ussp.rsi/meta.json
Resources/Textures/_Ganimed/Clothing/Uniforms/Jumpsuit/alt_centcom_officer.rsi/meta.json
Resources/Textures/_Ganimed/Clothing/Uniforms/Jumpsuit/cargopostal.rsi/meta.json
Resources/Textures/_Ganimed/Clothing/Uniforms/Jumpsuit/dec.rsi/meta.json
Resources/Textures/_Ganimed/Markers/jobs.rsi/meta.json
Resources/Textures/_Ganimed/Structures/Machines/fax_machine.rsi/meta.json

Trailing whitespace

Resources/Locale/ru-RU/_Ganimed/game-ticking/game-presets/preset-conspirator.ftl
  Line 7

Resources/ServerInfo/_Ganimed/Guidebook/ServerRules/Ruleset.xml
  Line 4

Быстро исправить можно так:

python - <<'PY'
from pathlib import Path

missing_eof_lf = [
    "Resources/Locale/en-US/_Ganimed/paper/signature.ftl",
    "Resources/Locale/en-US/_Ganimed/station-events/events/events.ftl",
    "Resources/Prototypes/_Ganimed/Entities/Personalization/personalization_clothing.yml",
    "Resources/Textures/_Ganimed/Clothing/Head/Hats/officer_cap.rsi/meta.json",
    "Resources/Textures/_Ganimed/Clothing/Head/Helmets/pilothelmet.rsi/meta.json",
    "Resources/Textures/_Ganimed/Clothing/Head/Soft/cargopostalsoft.rsi/meta.json",
    "Resources/Textures/_Ganimed/Clothing/Neck/Cloaks/chaplain_black.rsi/meta.json",
    "Resources/Textures/_Ganimed/Clothing/Neck/Cloaks/chaplain_white.rsi/meta.json",
    "Resources/Textures/_Ganimed/Clothing/Neck/Cloaks/sanabi.rsi/meta.json",
    "Resources/Textures/_Ganimed/Clothing/Neck/Cloaks/whitebelov.rsi/meta.json",
    "Resources/Textures/_Ganimed/Clothing/Neck/Mantles/alt_capmantle.rsi/meta.json",
    "Resources/Textures/_Ganimed/Clothing/Neck/Mantles/bridge_officer_mantle.rsi/meta.json",
    "Resources/Textures/_Ganimed/Clothing/Neck/Mantles/original_cemantle.rsi/meta.json",
    "Resources/Textures/_Ganimed/Clothing/Neck/Mantles/original_rdmantle.rsi/meta.json",
    "Resources/Textures/_Ganimed/Clothing/OuterClothing/Coats/original_labcoat_robo.rsi/meta.json",
    "Resources/Textures/_Ganimed/Clothing/OuterClothing/WinterCoats/wintercoatseniorengineer.rsi/meta.json",
    "Resources/Textures/_Ganimed/Clothing/OuterClothing/WinterCoats/wintercoatseniorofficer.rsi/meta.json",
    "Resources/Textures/_Ganimed/Clothing/OuterClothing/WinterCoats/wintercoatseniorphysican.rsi/meta.json",
    "Resources/Textures/_Ganimed/Clothing/OuterClothing/WinterCoats/wintercoatseniorresearcher.rsi/meta.json",
    "Resources/Textures/_Ganimed/Clothing/Uniforms/Jumpskirt/cargopostal.rsi/meta.json",
    "Resources/Textures/_Ganimed/Clothing/Uniforms/Jumpskirt/clownskirtsuit.rsi/meta.json",
    "Resources/Textures/_Ganimed/Clothing/Uniforms/Jumpskirt/dec.rsi/meta.json",
    "Resources/Textures/_Ganimed/Clothing/Uniforms/Jumpsuit/USSP/sponsor_ussp.rsi/meta.json",
    "Resources/Textures/_Ganimed/Clothing/Uniforms/Jumpsuit/alt_centcom_officer.rsi/meta.json",
    "Resources/Textures/_Ganimed/Clothing/Uniforms/Jumpsuit/cargopostal.rsi/meta.json",
    "Resources/Textures/_Ganimed/Clothing/Uniforms/Jumpsuit/dec.rsi/meta.json",
    "Resources/Textures/_Ganimed/Markers/jobs.rsi/meta.json",
    "Resources/Textures/_Ganimed/Structures/Machines/fax_machine.rsi/meta.json",
]

trailing_ws = [
    "Resources/Locale/ru-RU/_Ganimed/game-ticking/game-presets/preset-conspirator.ftl",
    "Resources/ServerInfo/_Ganimed/Guidebook/ServerRules/Ruleset.xml",
]

for file in missing_eof_lf:
    path = Path(file)
    data = path.read_bytes()
    if data and not data.endswith(b"\n"):
        path.write_bytes(data + b"\n")

for file in trailing_ws:
    path = Path(file)
    text = path.read_text(encoding="utf-8-sig")
    lines = text.splitlines(keepends=True)
    fixed = "".join(
        line.rstrip(" \t\r\n") + ("\n" if line.endswith(("\n", "\r")) else "")
        for line in lines
    )
    path.write_text(fixed, encoding="utf-8")
PY

@github-actions

github-actions Bot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

RSI Diff Bot; head commit c0f2bc5 merging into bcf6d90
This PR makes changes to 1 or more RSIs. Here is a summary of all changes:

Resources/Textures/_Ganimed/Clothing/Back/Backpacks/bridge_officer_backpack.rsi

State Old New Status
equipped-BACKPACK Modified
icon Modified
inhand-left Modified
inhand-right Modified

Resources/Textures/_Ganimed/Clothing/Back/Backpacks/cargo_dark.rsi

State Old New Status
equipped-BACKPACK Modified
icon Modified
inhand-left Modified
inhand-right Modified

Resources/Textures/_Ganimed/Clothing/Back/Backpacks/cmo.rsi

State Old New Status
equipped-BACKPACK Modified
icon Modified
inhand-left Modified
inhand-right Modified

Resources/Textures/_Ganimed/Clothing/Back/Backpacks/cooler_bag.rsi

State Old New Status
equipped-BACKPACK Modified
icon Modified
inhand-left Modified
inhand-right Modified

Resources/Textures/_Ganimed/Clothing/Back/Backpacks/hop.rsi

State Old New Status
equipped-BACKPACK Modified
icon Modified
inhand-left Modified
inhand-right Modified

Edit: diff updated after c0f2bc5

@github-actions github-actions Bot added the Changes: Audio Изменения в звуковой составляющей игры, такие как звуковые эффекты и музыка. label Jun 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A: GitHub/Workflows Area: Изменение в рабочем процессе репозитория GitHub Changes: Audio Изменения в звуковой составляющей игры, такие как звуковые эффекты и музыка. Changes: Localization Изменения затрагивают локализацию. Changes: Sprites Changes: UI P3: Standard Стандартный приоритет рассмотрения S: Needs Review Status: Требуется рассмотрение size/M T: Maintenance Type: Синхронизация с апстримом, обновления чейнджлога и пр.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant