Files
YandexMusic/CONTRIBUTING.md
2026-04-21 12:51:23 +03:00

411 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 🤝 Руководство для участников
Спасибо за интерес к проекту YandexMusic! Этот документ содержит рекомендации для тех, кто хочет внести свой вклад в развитие проекта.
## 📋 Содержание
- [Кодекс поведения](#кодекс-поведения)
- [Как начать](#как-начать)
- [Процесс разработки](#процесс-разработки)
- [Стандарты кода](#стандарты-кода)
- [Commit сообщения](#commit-сообщения)
- [Pull Requests](#pull-requests)
- [Отчёты об ошибках](#отчёты-об-ошибках)
- [Предложения по улучшениям](#предложения-по-улучшениям)
## 🤐 Кодекс поведения
- Будьте уважительны к другим участникам
- Не допускайте дискриминацию, оскорбления и враждебного поведения
- Критикуйте идеи, а не людей
- Решайте конфликты конструктивно
## 🚀 Как начать
### 1. Подготовка окружения
```bash
# Клонируем репозиторий
git clone https://git.frigat.duckdns.org/FrigaT/YandexMusic.git
cd YandexMusic
# Создаём ветку для своей работы
git checkout -b feature/my-feature
# Восстанавливаем зависимости
dotnet restore
# Собираем проект
dotnet build
```
### 2. Установка инструментов
- **Visual Studio 2026 Enterprise** (рекомендуется)
- **Visual Studio Code** + C# extension (альтернатива)
- **.NET 10 SDK**
### 3. Запуск тестов
```bash
dotnet test
```
## 🔄 Процесс разработки
### Workflow
```
1. Выберите issue или создайте новый
2. Создайте feature-ветку
3. Внесите изменения
4. Напишите/обновите тесты
5. Убедитесь что код собирается и тесты проходят
6. Создайте Pull Request
7. Ждите review
8. Исправьте замечания если нужно
9. Merge в master
```
### Версионирование веток
```
master → Production версия
├── feature/* → Новые функции
├── bugfix/* → Исправления ошибок
├── refactor/* → Рефакторинг кода
└── docs/* → Обновления документации
```
## 📐 Стандарты кода
### Общие правила
- **Язык:** C# 12
- **Платформа:** .NET 10
- **Стиль:** Microsoft C# Coding Conventions
- **Документация:** Все публичные члены должны иметь XML документацию на русском
### Пример документированного кода
```csharp
namespace YandexMusic.API.API;
/// <summary>API для работы с альбомами.</summary>
public class YAlbumAPI : YCommonAPI
{
/// <summary>Инициализирует новый экземпляр.</summary>
/// <param name="yandex">Экземпляр основного API.</param>
public YAlbumAPI(YandexMusicApi yandex) : base(yandex) { }
/// <summary>Получает информацию об альбоме по идентификатору.</summary>
/// <param name="albumId">Идентификатор альбома</param>
/// <returns>Модель альбома или null если не найден</returns>
/// <exception cref="ArgumentNullException">Если albumId null</exception>
public async Task<YAlbum?> GetAlbumAsync(string albumId)
{
ArgumentNullException.ThrowIfNull(albumId);
// Реализация
return await Task.FromResult<YAlbum?>(null);
}
}
```
### Правила именования
```csharp
// Классы: PascalCase
public class YandexMusicApi { }
// Методы: PascalCase с Async суффиксом для асинхронных
public async Task<YTrack?> GetTrackAsync(string trackId) { }
// Свойства: PascalCase
public YandexMusicApi Api { get; }
// Приватные поля: _camelCase
private readonly HttpClient _httpClient;
// Параметры: camelCase
public void DoSomething(string userName, int userId) { }
// Локальные переменные: camelCase
var trackList = new List<YTrack>();
```
### Code Style
Используйте `.editorconfig` для автоматического форматирования:
```ini
# Отступы - 4 пробела
indent_size = 4
# Новая строка для фигурных скобок
csharp_new_line_before_open_brace = all
# Используйте var где возможно
csharp_style_var_for_built_in_types = true
# Null-forgiving operator с осторожностью
csharp_style_null_forgiving_operator = false
```
### Nullable Reference Types
Всегда включен `<Nullable>enable</Nullable>`. Правила:
```csharp
// ✅ Хорошо - явно указано может быть null
public string? GetUserName() { }
// ✅ Хорошо - явно не null
public string GetTitle() => "Title";
// ❌ Плохо - неявная nullable ссылка
public object GetSomething() { }
// ✅ Хорошо - используйте null-coalescing
var result = value ?? defaultValue;
// ✅ Хорошо - используйте null-conditional
var count = list?.Count ?? 0;
```
### Асинхронное программирование
```csharp
// ✅ Хорошо - async/await
public async Task<YTrack?> GetTrackAsync(string id)
{
return await api.Track.GetTrackAsync(id);
}
// ❌ Плохо - Task.Result блокирует поток
public YTrack? GetTrack(string id)
{
return api.Track.GetTrackAsync(id).Result;
}
// ✅ Хорошо - ConfigureAwait(false) в библиотеках
public async Task<YTrack?> GetTrackAsync(string id)
{
return await api.Track.GetTrackAsync(id).ConfigureAwait(false);
}
```
### Обработка ошибок
```csharp
// ✅ Хорошо
public async Task<YTrack?> GetTrackAsync(string trackId)
{
ArgumentNullException.ThrowIfNull(trackId);
ArgumentException.ThrowIfNullOrWhiteSpace(trackId);
try
{
return await _provider.GetTrackAsync(trackId);
}
catch (HttpRequestException ex)
{
Logger.LogError(ex, "Ошибка при получении трека");
throw;
}
}
// ❌ Плохо - молча игнорируем ошибки
public async Task<YTrack?> GetTrackAsync(string trackId)
{
try
{
return await _provider.GetTrackAsync(trackId);
}
catch { }
return null;
}
```
### Структура файла
```csharp
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace YandexMusic.API.API;
/// <summary>API для работы с треками.</summary>
public class YTrackAPI : YCommonAPI
{
/// <summary>Инициализирует новый экземпляр.</summary>
public YTrackAPI(YandexMusicApi yandex) : base(yandex) { }
/// <summary>Получает трек.</summary>
public async Task<YTrack?> GetTrackAsync(string trackId)
{
// реализация
}
/// <summary>Получает несколько треков.</summary>
public async Task<IEnumerable<YTrack>> GetTracksAsync(IEnumerable<string> trackIds)
{
// реализация
}
}
```
## 📝 Commit сообщения
### Формат
```
<type>(<scope>): <subject>
<body>
<footer>
```
### Type
- `feat:` - новая функция
- `fix:` - исправление ошибки
- `docs:` - обновление документации
- `style:` - форматирование кода (не влияет на функциональность)
- `refactor:` - переписывание кода (не меняет функциональность)
- `perf:` - улучшение производительности
- `test:` - добавление или обновление тестов
- `ci:` - изменения в CI/CD
- `chore:` - обновление зависимостей, версии и т.д.
### Примеры
```bash
git commit -m "feat(track-api): add support for track recommendations"
git commit -m "fix(auth): handle refresh token expiration correctly"
git commit -m "docs(readme): update installation instructions"
git commit -m "refactor(models): simplify YTrack class structure"
git commit -m "test(playlist): add tests for playlist operations"
```
## 🔀 Pull Requests
### Перед созданием PR
- [ ] Код собирается без ошибок: `dotnet build`
- [ ] Все тесты проходят: `dotnet test`
- [ ] Код отформатирован согласно стилю
- [ ] Добавлена XML документация для всех публичных членов
- [ ] Обновлена документация если нужно
### Шаблон PR
```markdown
## Описание
Краткое описание внесённых изменений.
## Тип изменения
- [ ] Новая функция (non-breaking change)
- [ ] Исправление ошибки (non-breaking change)
- [ ] Breaking change (поясните почему)
- [ ] Обновление документации
## Как это было протестировано?
Опишите шаги для тестирования.
## Связанные Issues
Closes #issue_number
## Чеклист
- [ ] Код следует стилю проекта
- [ ] Добавлена документация
- [ ] Нет новых warnings
- [ ] Тесты проходят
- [ ] Изменения совместимы с существующим кодом
```
## 🐛 Отчёты об ошибках
### Шаблон Issue
```markdown
## Описание ошибки
Четкое и краткое описание проблемы.
## Шаги воспроизведения
1. Сделайте...
2. Затем...
3. Ошибка воспроизведится
## Ожидаемое поведение
Что должно было происходить.
## Фактическое поведение
Что происходит на самом деле.
## Окружение
- OS: Windows 11
- .NET Version: 10.0
- Visual Studio: 2026 Enterprise
- YandexMusic Version: 0.0.1
## Дополнительный контекст
Скриптстек, логи, код примера.
```
## 💡 Предложения по улучшениям
### Шаблон Feature Request
```markdown
## Описание
Четкое описание желаемой функции.
## Использование
Как бы выглядел код с использованием этой функции?
## Альтернативы
Есть ли другие способы решить эту проблему?
## Дополнительный контекст
Почему это нужно добавить?
```
## 🎯 Области для внесения вклада
### High Priority
- [ ] Документация API методов
- [ ] Unit тесты для API классов
- [ ] Обработка ошибок
- [ ] Оптимизация производительности
### Medium Priority
- [ ] Примеры использования
- [ ] Интеграционные тесты
- [ ] Улучшение логирования
- [ ] Расширение функциональности
### Low Priority
- [ ] Рефакторинг кода
- [ ] Улучшение читаемости
- [ ] Документация
## 📞 Контакты
Вопросы? Свяжитесь с разработчиком:
- **Issues:** [https://git.frigat.duckdns.org/FrigaT/YandexMusic/issues]
---
Спасибо за то, что делаете YandexMusic лучше! 🚀