Conversation
namespace-wide only REUSE headers implementation without moving the licenses See https://reuse.software/ Also reformatted EOL from CRLF to LF in _Ganimed folders.
|
Important Review skippedToo many files! This PR contains 278 files, which is 128 over the limit of 150. To get a review, narrow the scope: ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (22)
📒 Files selected for processing (278)
You can disable this status message by setting the Use the checkbox below for a quick retry:
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. Comment |
|
@coderabbitai review --dir .github |
|
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 | sortLength 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.pyLength 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 ""
doneLength of output: 57380
Обзор
|
| 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-директорий).
|
@coderabbitai review --dir Tools/ganimed |
|
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 | sortLength 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 ""
doneLength of output: 48292
Обзор
|
|
@coderabbitai мне нужно сделать так, чтобы workflow |
|
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.pyLength of output: 17534
|
|
@coderabbitai review --dir |
|
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 | sortLength 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 -120Length 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 ""
doneLength of output: 5332
Обзор корневой директории🟠 REUSE-совместимость1. Отсутствует В
Но в файлах 2. Нет Для прохождения 3. Директория 🟡 Форматирование4. BOM в Файл sed -i 's/^\xEF\xBB\xBF//' .editorconfig5. Дублирующиеся файлы лицензий в корне В корне присутствуют:
Для REUSE-совместимости каноническими являются файлы в 🟡 Прочее6. Это upstream-артефакты от Corvax-форка. Если они не используются — стоит убрать, чтобы не вводить в заблуждение контрибьюторов. 7. Как упоминалось в предыдущем обзоре — ✅ Что сделано хорошо
|
|
@coderabbitai в каких файлах в субдиректориях |
|
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]}")
PYLength of output: 7526
Нет EOF LFTrailing whitespaceБыстро исправить можно так: 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 |
|
RSI Diff Bot; head commit c0f2bc5 merging into bcf6d90 Resources/Textures/_Ganimed/Clothing/Back/Backpacks/bridge_officer_backpack.rsi
Resources/Textures/_Ganimed/Clothing/Back/Backpacks/cargo_dark.rsi
Resources/Textures/_Ganimed/Clothing/Back/Backpacks/cmo.rsi
Resources/Textures/_Ganimed/Clothing/Back/Backpacks/cooler_bag.rsi
Resources/Textures/_Ganimed/Clothing/Back/Backpacks/hop.rsi
|






























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